home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / lang / cplus / 12995 < prev    next >
Encoding:
Text File  |  1992-08-27  |  22.8 KB  |  705 lines

  1. Path: sparky!uunet!elroy.jpl.nasa.gov!swrinde!news.dell.com!math.utexas.edu!ut-emx!jamshid
  2. From: jamshid@ut-emx.uucp (Jamshid Afshar)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: How do I write a typedef to go with my template class?
  5. Keywords: template generic define
  6. Message-ID: <78539@ut-emx.uucp>
  7. Date: 27 Aug 92 23:41:15 GMT
  8. References: <ghawkins.714856261@unix1.tcd.ie>
  9. Organization: The University of Texas at Austin; Austin, Texas
  10. Lines: 693
  11.  
  12. In article <ghawkins.714856261@unix1.tcd.ie> ghawkins@unix1.tcd.ie (George C. Hawkins) writes:
  13. >    template <class X>
  14. >    class Callback {
  15. >        ...
  16. >    }
  17. >    typedef void (X::func_ptr)(int);
  18. >
  19. >And even if I could I'd get name clashes for all my typedefs for
  20. >Callback class being used with different X types.
  21.  
  22. The best you can do is a nested typedef (but at least that solves the
  23. naming problem).
  24.  
  25.     template<class X>
  26.     class Callback {
  27.     public:
  28.        typedef void (X::*PMF)(int);   // defines nested type name "PMF"
  29.        Callback(X* x, PMF f) { ... }
  30.        ...
  31.     };
  32.  
  33.     CallBack<Foo>::PMF mfp = &Foo::doit;  // define 'mfp' variable
  34.     Foo afoo;
  35.     Callback c(&afoo, mfp);  // defines callback 'c'
  36.  
  37. Warning, BC++ has trouble with nested typedefs.  Also, I'm appending
  38. my callback class templates.  See functor1.h for the (sparse)
  39. documentation and usage examples.
  40.  
  41. Jamshid Afshar
  42. jamshid@emx.utexas.edu
  43.  
  44. #! /bin/sh
  45. # This is a shell archive.  Remove anything before this line, then unpack
  46. # it by saving it into a file and typing "sh file".  To overwrite existing
  47. # files, type "sh file -c".  You can also feed this as standard input via
  48. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  49. # will see the following message at the end:
  50. #        "End of shell archive."
  51. # Contents:  functor0.h functor1.h functor2.h smartptr.h tstftor.cpp
  52. # Wrapped by jamshid@emx.utexas.edu on Mon Mar 23 14:55:15 1992
  53. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  54. if test -f 'functor0.h' -a "${1}" != "-c" ; then 
  55.   echo shar: Will not clobber existing file \"'functor0.h'\"
  56. else
  57. echo shar: Extracting \"'functor0.h'\" \(3334 characters\)
  58. sed "s/^X//" >'functor0.h' <<'END_OF_FILE'
  59. X/****************************************************************************
  60. X*  File: functor0.h
  61. X*  
  62. X*  Description:
  63. X*     Defines the Functor0<R> class template and Functor0v class and the
  64. X*     functor(O*, R (O::*)()) and functorv(O*, void (O::*)()) function
  65. X*     templates which create the Functor objects.  These are Functors
  66. X*     taking zero parameters.  See functor1.h for a description of Functors.
  67. X*
  68. X*  Usage:
  69. X*     See functor1.h
  70. X*
  71. X*  Notes:
  72. X*     See functor1.h.  Functor0v is not a template.
  73. X*
  74. X*  History:
  75. X*  14 Feb 1992 Jam      created from functor1.h -- replaced "{, }@class P1",
  76. X*                       "P1 p1", "{, }P1>", "P1)", "p1"
  77. X*  19 Feb 1992 Jam      renamed functorN() back to functor(), overloadable:-)
  78. X*  20 Mar 1992 Jam      added null() and void* conversion: `if (f1)'
  79. X*  20 Mar 1992 Jam      restructured -- Functor1 now contains ptr
  80. X*     
  81. X****************************************************************************/     
  82. X#ifndef JAM_FUNCTOR0_H
  83. X#define JAM_FUNCTOR0_H
  84. X
  85. X#include "smartptr.h"
  86. X
  87. X//**************************************************************************
  88. X// Defines Functor0<R>, functor(O*, R (O::*)()) and helper classes
  89. X//**************************************************************************
  90. X
  91. X   template<class R>
  92. Xclass AbstractFunctor0 : public JAM_ReferenceCounter {
  93. Xpublic:
  94. X   virtual R call() const = 0;
  95. X   virtual int null() const = 0;
  96. X};
  97. X
  98. X   template<class R>
  99. Xclass Functor0 {
  100. X   JAM_SmartPtr< AbstractFunctor0<R> > _ptr;
  101. Xpublic:
  102. X   Functor0(AbstractFunctor0<R>* ptr = 0) : _ptr(ptr) {}
  103. X   R operator()() const { return _ptr->call(); }
  104. X   operator const void*() const
  105. X      { return (_ptr==0 || _ptr->null()) ? 0 : this; }
  106. X};
  107. X
  108. X   template<class O, class R>
  109. Xclass ConcreteFunctor0 : public AbstractFunctor0<R> {
  110. Xpublic:
  111. X   ConcreteFunctor0(O* object, R (O::*method)())
  112. X      : _object(object), _method(method) {}
  113. X   virtual R call() const { return (_object->*_method)(); }
  114. X   virtual int null() const { return _object==0 || _method==0; }
  115. Xprotected:
  116. X   O* _object;
  117. X   R (O::*_method)();
  118. X};
  119. X
  120. X   template<class O, class R> inline
  121. XFunctor0<R> functor(O* object, R (O::*method)()) {
  122. X   return new ConcreteFunctor0<O, R>(object, method);
  123. X}
  124. X
  125. X
  126. X//**************************************************************************
  127. X// Defines Functor0v, functorv(O*, void (O::*)()) and helper classes
  128. X//**************************************************************************
  129. X
  130. Xclass AbstractFunctor0v : public JAM_ReferenceCounter {
  131. Xpublic:
  132. X   virtual void call() const = 0;
  133. X   virtual int null() const = 0;
  134. X};
  135. X
  136. Xclass Functor0v {
  137. X   JAM_SmartPtr< AbstractFunctor0v > _ptr;
  138. Xpublic:
  139. X   Functor0v(AbstractFunctor0v* ptr = 0) : _ptr(ptr) {}
  140. X   void operator()() const { _ptr->call(); }
  141. X   operator const void*() const
  142. X      { return (_ptr==0 || _ptr->null()) ? 0 : this; }
  143. X};
  144. X
  145. X   template<class O>
  146. Xclass ConcreteFunctor0v : public AbstractFunctor0v {
  147. Xpublic:
  148. X   ConcreteFunctor0v(O* object, void (O::*method)())
  149. X      : _object(object), _method(method) {}
  150. X   virtual void call() const { (_object->*_method)(); }
  151. X   virtual int null() const { return _object==0 || _method==0; }
  152. Xprotected:
  153. X   O* _object;
  154. X   void (O::*_method)();
  155. X};
  156. X
  157. X   template<class O> inline
  158. XFunctor0v functorv(O* object, void (O::*method)()) {
  159. X   return new ConcreteFunctor0v<O>(object, method);
  160. X}
  161. X
  162. X
  163. X#endif // JAM_FUNCTOR0_H
  164. X
  165. END_OF_FILE
  166. if test 3334 -ne `wc -c <'functor0.h'`; then
  167.     echo shar: \"'functor0.h'\" unpacked with wrong size!
  168. fi
  169. # end of 'functor0.h'
  170. fi
  171. if test -f 'functor1.h' -a "${1}" != "-c" ; then 
  172.   echo shar: Will not clobber existing file \"'functor1.h'\"
  173. else
  174. echo shar: Extracting \"'functor1.h'\" \(5011 characters\)
  175. sed "s/^X//" >'functor1.h' <<'END_OF_FILE'
  176. X/****************************************************************************
  177. X*  File: functor1.h
  178. X*  
  179. X*  Description:
  180. X*     Defines Functor1<R, P1> and Functor1v<P1> class templates and
  181. X*     functor(O*, R (O::*)(P1)) and functorv(O*, void (O::*)(P1)) function
  182. X*     templates which create Functor objects.  A Functor is used as if
  183. X*     it were a pointer to a function taking a P1 parameter and returning
  184. X*     an R.  Functor1v is just like Functor1 except it returns void
  185. X*     (there is no R).
  186. X*     
  187. X*     Functors actually contain a pointer to an object and a pointer to one
  188. X*     of the object's member functions.  These two pointers are specified
  189. X*     when calling functor().  The member function must take a parameter P1
  190. X*     and returns R.  When the Functor is executed, that member function is
  191. X*     called on the object.  Since the code using a Functor only has to
  192. X*     specify the type of the member function parameters and return type,
  193. X*     not the type of the object actually receiving the message, using
  194. X*     Functors makes the code more general.
  195. X*
  196. X*
  197. X*  Usage:
  198. X*     class Foo {
  199. X*     public:
  200. X*        int addstr(const String& newstr);
  201. X*        void scroll(double percent);
  202. X*     } afoo;
  203. X*     Functor1<int, const String&> f1 = functor(&afoo, &Foo::addstr);
  204. X*     if ( f1("new entry")==0 ) cerr << "Couldn't add string.\n";
  205. X*     Functor1v<double> f2 = functorv(&afoo, &Foo::scroll);
  206. X*     f2(0.5);    // scroll Foo by 50%
  207. X*     Functor1v<double> f3 = 0;
  208. X*     if (f3!=0) f3(1.23);
  209. X*
  210. X*  Notes:
  211. X*     Below, the template parameter O is the type of the object whose
  212. X*     member function will be called.  The return type of the member
  213. X*     function is R (but there is none for Functor1v).  The member
  214. X*     function takes one parameter of type P1.
  215. X*
  216. X*  History:
  217. X*  12 Feb 1992 Jam      created; referenced Coplien
  218. X*  13 Feb 1992 Jam      added operator() functionality to a derived SmartPtr
  219. X*  13 Feb 1992 Jam      added Functor1v for functors returning void (no R)
  220. X*  14 Feb 1992 Jam      renamed functor[v]() functor1[v]() because of functor2.h
  221. X*  19 Feb 1992 Jam      renamed functorN() back to functor(), overloadable:-)
  222. X*  20 Mar 1992 Jam      added null() and void* conversion: `if (f1)'
  223. X*  20 Mar 1992 Jam      restructured -- Functor1 now contains a ptr
  224. X*                       instead of inheriting from it
  225. X*     
  226. X****************************************************************************/     
  227. X#ifndef JAM_FUNCTOR1_H
  228. X#define JAM_FUNCTOR1_H
  229. X
  230. X#include "smartptr.h"
  231. X
  232. X//**************************************************************************
  233. X// Defines Functor1<R, P1>, functor(O*, R (O::*)(P1)) and helper classes
  234. X//**************************************************************************
  235. X
  236. X   template<class R, class P1>
  237. Xclass AbstractFunctor1 : public JAM_ReferenceCounter {
  238. Xpublic:
  239. X   virtual R call(P1 p1) const = 0;
  240. X   virtual int null() const = 0;
  241. X};
  242. X
  243. X   template<class R, class P1>
  244. Xclass Functor1 {
  245. X   JAM_SmartPtr< AbstractFunctor1<R, P1> > _ptr;
  246. Xpublic:
  247. X   Functor1(AbstractFunctor1<R, P1>* ptr = 0) : _ptr(ptr) {}
  248. X   R operator()(P1 p1) const { return _ptr->call(p1); }
  249. X   operator const void*() const
  250. X      { return (_ptr==0 || _ptr->null()) ? 0 : this; }
  251. X};
  252. X
  253. X   template<class O, class R, class P1>
  254. Xclass ConcreteFunctor1 : public AbstractFunctor1<R, P1> {
  255. Xpublic:
  256. X   ConcreteFunctor1(O* object, R (O::*method)(P1))
  257. X      : _object(object), _method(method) {}
  258. X   virtual R call(P1 p1) const { return (_object->*_method)(p1); }
  259. X   virtual int null() const { return _object==0 || _method==0; }
  260. Xprotected:
  261. X   O* _object;
  262. X   R (O::*_method)(P1 p1);
  263. X};
  264. X
  265. X   template<class O, class R, class P1> inline
  266. XFunctor1<R, P1> functor(O* object, R (O::*method)(P1)) {
  267. X   return new ConcreteFunctor1<O, R, P1>(object, method);
  268. X}
  269. X
  270. X
  271. X//**************************************************************************
  272. X// Defines Functor1v<P1>, functorv(O*, void (O::*)(P1)) and helper classes
  273. X//**************************************************************************
  274. X
  275. X   template<class P1>
  276. Xclass AbstractFunctor1v : public JAM_ReferenceCounter {
  277. Xpublic:
  278. X   virtual void call(P1 p1) const = 0;
  279. X   virtual int null() const = 0;
  280. X};
  281. X
  282. X   template<class P1>
  283. Xclass Functor1v {
  284. X   JAM_SmartPtr< AbstractFunctor1v<P1> > _ptr;
  285. Xpublic:
  286. X   Functor1v(AbstractFunctor1v<P1>* ptr) : _ptr(ptr) {}
  287. X   void operator()(P1 p1) const { _ptr->call(p1); }
  288. X   operator const void*() const
  289. X      { return (_ptr==0 || _ptr->null()) ? 0 : this; }
  290. X};
  291. X
  292. X   template<class O, class P1>
  293. Xclass ConcreteFunctor1v : public AbstractFunctor1v<P1> {
  294. Xpublic:
  295. X   ConcreteFunctor1v(O* object, void (O::*method)(P1))
  296. X      : _object(object), _method(method) {}
  297. X   virtual void call(P1 p1) const { (_object->*_method)(p1); }
  298. X   virtual int null() const { return _object==0 || _method==0; }
  299. Xprotected:
  300. X   O* _object;
  301. X   void (O::*_method)(P1 p1);
  302. X};
  303. X
  304. X   template<class O, class P1> inline
  305. XFunctor1v<P1> functorv(O* object, void (O::*method)(P1)) {
  306. X   return new ConcreteFunctor1v<O, P1>(object, method);
  307. X}
  308. X
  309. X
  310. X#endif // JAM_FUNCTOR1_H
  311. X
  312. END_OF_FILE
  313. if test 5011 -ne `wc -c <'functor1.h'`; then
  314.     echo shar: \"'functor1.h'\" unpacked with wrong size!
  315. fi
  316. # end of 'functor1.h'
  317. fi
  318. if test -f 'functor2.h' -a "${1}" != "-c" ; then 
  319.   echo shar: Will not clobber existing file \"'functor2.h'\"
  320. else
  321. echo shar: Extracting \"'functor2.h'\" \(3824 characters\)
  322. sed "s/^X//" >'functor2.h' <<'END_OF_FILE'
  323. X/****************************************************************************
  324. X*  File: functor2.h
  325. X*  
  326. X*  Description:
  327. X*     Defines the Functor2<R, P1, P2> and Functor2v<P1, P2> class
  328. X*     templates and the functor(O*, R (O::*)(P1, P2)) and
  329. X*     functorv(O*, void (O::*)(P1, P2)) function templates which create
  330. X*     the Functor objects.  These are Functors taking two parameters
  331. X*     See functor1.h for a description of Functors.
  332. X*
  333. X*
  334. X*  Usage:
  335. X*     See functor1.h
  336. X*
  337. X*  Notes:
  338. X*     See functor1.h
  339. X*
  340. X*  History:
  341. X*  14 Feb 1992 Jam      created from functor1.h -- replaced "class P1",
  342. X*                       "P1 p1", "P1>", "P1)", "p1)"
  343. X*  14 Feb 1992 Jam      had to rename functor[v]() functor2[v]()
  344. X*  19 Feb 1992 Jam      renamed functorN() back to functor(), overloadable:-)
  345. X*  20 Mar 1992 Jam      added null() and void* conversion: `if (f1)'
  346. X*  20 Mar 1992 Jam      restructured -- Functor1 now contains ptr
  347. X*     
  348. X****************************************************************************/     
  349. X#ifndef JAM_FUNCTOR2_H
  350. X#define JAM_FUNCTOR2_H
  351. X
  352. X#include "smartptr.h"
  353. X
  354. X//**************************************************************************
  355. X// Defines Functor2<R, P1, P2>, functor(O*, R (O::*)(P1, P2)) and helper classes
  356. X//**************************************************************************
  357. X
  358. X   template<class R, class P1, class P2>
  359. Xclass AbstractFunctor2 : public JAM_ReferenceCounter {
  360. Xpublic:
  361. X   virtual R call(P1 p1, P2 p2) const = 0;
  362. X   virtual int null() const = 0;
  363. X};
  364. X
  365. X   template<class R, class P1, class P2>
  366. Xclass Functor2 {
  367. X   JAM_SmartPtr< AbstractFunctor2<R, P1, P2> > _ptr;
  368. Xpublic:
  369. X   Functor2(AbstractFunctor2<R, P1, P2>* ptr = 0) : _ptr(ptr) {}
  370. X   R operator()(P1 p1, P2 p2) const { return _ptr->call(p1, p2); }
  371. X   operator const void*() const
  372. X      { return (_ptr==0 || _ptr->null()) ? 0 : this; }
  373. X};
  374. X
  375. X   template<class O, class R, class P1, class P2>
  376. Xclass ConcreteFunctor2 : public AbstractFunctor2<R, P1, P2> {
  377. Xpublic:
  378. X   ConcreteFunctor2(O* object, R (O::*method)(P1, P2))
  379. X      : _object(object), _method(method) {}
  380. X   virtual R call(P1 p1, P2 p2) const { return (_object->*_method)(p1, p2); }
  381. X   virtual int null() const { return _object==0 || _method==0; }
  382. Xprotected:
  383. X   O* _object;
  384. X   R (O::*_method)(P1 p1, P2 p2);
  385. X};
  386. X
  387. X   template<class O, class R, class P1, class P2> inline
  388. XFunctor2<R, P1, P2> functor(O* object, R (O::*method)(P1, P2)) {
  389. X   return new ConcreteFunctor2<O, R, P1, P2>(object, method);
  390. X}
  391. X
  392. X
  393. X//**************************************************************************
  394. X// Defines Functor2v<P1, P2>, functorv(O*, void (O::*)(P1, P2)) and helper classes
  395. X//**************************************************************************
  396. X
  397. X   template<class P1, class P2>
  398. Xclass AbstractFunctor2v : public JAM_ReferenceCounter {
  399. Xpublic:
  400. X   virtual void call(P1 p1, P2 p2) const = 0;
  401. X   virtual int null() const = 0;
  402. X};
  403. X
  404. X   template<class P1, class P2>
  405. Xclass Functor2v {
  406. X   JAM_SmartPtr< AbstractFunctor2v<P1, P2> > _ptr;
  407. Xpublic:
  408. X   Functor2v(AbstractFunctor2v<P1, P2>* ptr = 0) : _ptr(ptr) {}
  409. X   void operator()(P1 p1, P2 p2) const { _ptr->call(p1, p2); }
  410. X   operator const void*() const
  411. X      { return (_ptr==0 || _ptr->null()) ? 0 : this; }
  412. X};
  413. X
  414. X   template<class O, class P1, class P2>
  415. Xclass ConcreteFunctor2v : public AbstractFunctor2v<P1, P2> {
  416. Xpublic:
  417. X   ConcreteFunctor2v(O* object, void (O::*method)(P1, P2))
  418. X      : _object(object), _method(method) {}
  419. X   virtual void call(P1 p1, P2 p2) const { (_object->*_method)(p1, p2); }
  420. X   virtual int null() const { return _object==0 || _method==0; }
  421. Xprotected:
  422. X   O* _object;
  423. X   void (O::*_method)(P1 p1, P2 p2);
  424. X};
  425. X
  426. X   template<class O, class P1, class P2> inline
  427. XFunctor2v<P1, P2> functorv(O* object, void (O::*method)(P1, P2)) {
  428. X   return new ConcreteFunctor2v<O, P1, P2>(object, method);
  429. X}
  430. X
  431. X
  432. X#endif // JAM_FUNCTOR2_H
  433. X
  434. END_OF_FILE
  435. if test 3824 -ne `wc -c <'functor2.h'`; then
  436.     echo shar: \"'functor2.h'\" unpacked with wrong size!
  437. fi
  438. # end of 'functor2.h'
  439. fi
  440. if test -f 'smartptr.h' -a "${1}" != "-c" ; then 
  441.   echo shar: Will not clobber existing file \"'smartptr.h'\"
  442. else
  443. echo shar: Extracting \"'smartptr.h'\" \(4533 characters\)
  444. sed "s/^X//" >'smartptr.h' <<'END_OF_FILE'
  445. X/****************************************************************************
  446. X*  File: smartptr.h
  447. X*  
  448. X*  Description:  JAM_ReferenceCounter class definition
  449. X*                JAM_SmartPtr template class
  450. X*     
  451. X*     A JAM_SmartPtr<T> object is just like a pointer but you don't have to
  452. X*     worry about memory leaks because it counts references.  Because
  453. X*     JAM_SmartPtrs behave just like regular pointers, they can alias the
  454. X*     same object.  T must derive from public JAM_ReferenceCounter (defined
  455. X*     above).  
  456. X*
  457. X*  Notes:
  458. X*     I have no idea how any of this would work when dealing with virtual
  459. X*     bases (MI).
  460. X*
  461. X*
  462. X*  History:
  463. X*  20 Dec 1991 Jam      created from my <generic.h> macro
  464. X*  12 Feb 1992 Jam      had to move defs of all SmartPtr funcs out of class
  465. X*                       because of a BC++ 3.0 bug when using functors
  466. X*  14 Feb 1992 Jam      made ~JAM_ReferenceCounter protected to prevent
  467. X*                       users from using delete
  468. X*  20 Mar 1992 Jam      changed operator void* to const void* for safety
  469. X*     
  470. X****************************************************************************/     
  471. X
  472. X#ifndef JAM_SMARTPTR_H
  473. X#define JAM_SMARTPTR_H
  474. X
  475. X#include <assert.h>
  476. X
  477. X//***************************************************************************
  478. X// JAM_ReferenceCounter definition
  479. X//***************************************************************************
  480. X
  481. Xclass JAM_ReferenceCounter {
  482. Xprivate:
  483. X   int _numrefs;     // number of SmartPtrs referencing me
  484. X   JAM_ReferenceCounter(const JAM_ReferenceCounter&); // hide me -- can't copy
  485. X   void operator=(const JAM_ReferenceCounter&);     // hide me -- can't copy
  486. Xprotected:
  487. X      // keep dtors protected so user can't `delete p;' -- we
  488. X      // delete ourselves if you only use SmartPtrs
  489. X   virtual ~JAM_ReferenceCounter() { assert(_numrefs==0); }
  490. Xpublic:
  491. X   JAM_ReferenceCounter() : _numrefs(0) {}
  492. X   int numRefs() const { return _numrefs; }
  493. X   void incRefs() { ++_numrefs; }
  494. X   void decRefs() {
  495. X      assert(_numrefs>0);
  496. X      if (--_numrefs==0) delete this;
  497. X      }
  498. X};
  499. X
  500. X
  501. X//***************************************************************************
  502. X// JAM_SmartPtr definition
  503. X//***************************************************************************
  504. X
  505. Xtemplate<class T> class JAM_SmartPtr {
  506. Xpublic:
  507. X   JAM_SmartPtr();
  508. X
  509. X   /* itemp MUST BE ON HEAP.  Do not use itemp after assignment. */
  510. X   JAM_SmartPtr(T* itemp); 
  511. X
  512. X   JAM_SmartPtr(const JAM_SmartPtr<T>& smrt); 
  513. X
  514. X   ~JAM_SmartPtr(); 
  515. X
  516. X   void operator=(const JAM_SmartPtr<T>& smrt); 
  517. X
  518. X   /* itemp MUST BE ON HEAP.  Do not use itemp after assignment */
  519. X   void operator=(T* itemp); 
  520. X
  521. X   /* does *NOT* call T == T */
  522. X   int operator==(const JAM_SmartPtr<T>& smrt); 
  523. X
  524. X   const T* operator->() const; 
  525. X   const T& operator*() const; 
  526. X
  527. X   T* operator->(); 
  528. X   T& operator*(); 
  529. X
  530. X   operator const void*() const { return _ptr; } // Borland bug doesn't allow definition outside
  531. X
  532. Xprotected:
  533. X   T* _ptr;
  534. X};
  535. X
  536. X
  537. X//***************************************************************************
  538. X// JAM_SmartPtr inlines
  539. X//***************************************************************************
  540. X
  541. Xtemplate<class T> inline
  542. XJAM_SmartPtr<T>::JAM_SmartPtr()
  543. X   : _ptr(0) {}
  544. X
  545. Xtemplate<class T> inline
  546. XJAM_SmartPtr<T>::JAM_SmartPtr(T* itemp)
  547. X   : _ptr(itemp) { if (_ptr) _ptr->incRefs(); }
  548. X
  549. X
  550. Xtemplate<class T> inline
  551. XJAM_SmartPtr<T>::JAM_SmartPtr(const JAM_SmartPtr<T>& smrt)
  552. X   : _ptr(smrt._ptr) { if (_ptr) _ptr->incRefs(); }
  553. X
  554. X
  555. Xtemplate<class T> inline
  556. XJAM_SmartPtr<T>::~JAM_SmartPtr() {
  557. X   if (_ptr) { _ptr->decRefs(); _ptr=0; }
  558. X}
  559. X
  560. Xtemplate<class T> inline
  561. Xvoid JAM_SmartPtr<T>::operator=(const JAM_SmartPtr<T>& smrt) {
  562. X   if (this==&smrt || _ptr==smrt._ptr) return;
  563. X   if (_ptr) _ptr->decRefs();
  564. X   _ptr = smrt._ptr;
  565. X   if (_ptr) _ptr->incRefs();
  566. X}
  567. X
  568. X
  569. Xtemplate<class T> inline
  570. Xvoid JAM_SmartPtr<T>::operator=(T* itemp) {
  571. X   assert(_ptr!=itemp); /* weird stuff happening */
  572. X   if (_ptr) _ptr->decRefs();
  573. X   _ptr = itemp;
  574. X   if (_ptr) _ptr->incRefs();
  575. X}
  576. X
  577. X
  578. Xtemplate<class T> inline
  579. Xint JAM_SmartPtr<T>::operator==(const JAM_SmartPtr<T>& smrt) {
  580. X   return _ptr==smrt._ptr;
  581. X}
  582. X
  583. X
  584. Xtemplate<class T> inline
  585. Xconst T* JAM_SmartPtr<T>::operator->() const {
  586. X   assert(_ptr != 0); return _ptr;
  587. X}
  588. X
  589. X
  590. Xtemplate<class T> inline
  591. Xconst T& JAM_SmartPtr<T>::operator*() const {
  592. X   assert(_ptr != 0); return *_ptr;
  593. X}
  594. X
  595. X
  596. Xtemplate<class T> inline
  597. XT* JAM_SmartPtr<T>::operator->() {
  598. X   assert(_ptr != 0); return _ptr;
  599. X}
  600. X
  601. Xtemplate<class T> inline
  602. XT& JAM_SmartPtr<T>::operator*() {
  603. X   assert(_ptr != 0); return *_ptr;
  604. X}
  605. X
  606. X#endif // JAM_SMARTPTR_H
  607. X
  608. END_OF_FILE
  609. if test 4533 -ne `wc -c <'smartptr.h'`; then
  610.     echo shar: \"'smartptr.h'\" unpacked with wrong size!
  611. fi
  612. # end of 'smartptr.h'
  613. fi
  614. if test -f 'tstftor.cpp' -a "${1}" != "-c" ; then 
  615.   echo shar: Will not clobber existing file \"'tstftor.cpp'\"
  616. else
  617. echo shar: Extracting \"'tstftor.cpp'\" \(2354 characters\)
  618. sed "s/^X//" >'tstftor.cpp' <<'END_OF_FILE'
  619. X// Just a simple, meaningless, but pretty comprehensive set of
  620. X// tests for my Functor classes
  621. X// by Jamshid Afshar.  All code is in the public domain.
  622. X
  623. X#include <iostream.h>
  624. X#include <assert.h>
  625. X#include "functor0.h"
  626. X#include "functor1.h"
  627. X#include "functor2.h"
  628. X
  629. Xclass Model {
  630. Xpublic:
  631. X   int save1() { cout << "save1" << endl; return -3; }
  632. X   void save2() { cout << "save2" << endl; }
  633. X   int enter1(const char* s) { cout << s << endl; return -1; }
  634. X   void enter2(char c) { cout << c << endl; }
  635. X   int enterat1(int i, const char* s) { cout << i << ',' << s << endl; return -2; }
  636. X   void enterat2(int i, const char* s) { cout << i << ',' << s << endl; }
  637. X};
  638. X
  639. Xtypedef Functor1<int,const char*> FP1;
  640. Xtypedef Functor1v<char> FP2;
  641. Xtypedef Functor0<int> FP3;
  642. Xtypedef Functor0v FP4;
  643. Xtypedef Functor2<int, int, const char*> FP5;
  644. Xtypedef Functor2v<int, const char*> FP6;
  645. X
  646. Xclass View {
  647. X   FP1 _f1;
  648. X   FP2 _f2;
  649. X   FP3 _f3;
  650. X   FP4 _f4;
  651. X   FP5 _f5;
  652. X   FP6 _f6;
  653. Xpublic:
  654. X   View(const FP1& f1, const FP2& f2, const FP3& f3, const FP4& f4, const FP5& f5, const FP6& f6)
  655. X      : _f1(f1), _f2(f2), _f3(f3), _f4(f4), _f5(f5), _f6(f6) {}
  656. X   void input() {
  657. X      if (_f1) cout << _f1("Hello") << endl;
  658. X      else cout << "_f1==0" << endl;
  659. X      if (_f2) _f2('J');
  660. X      else cout << "_f2==0" << endl;
  661. X      if (_f3) cout << _f3() << endl;
  662. X      else cout << "_f3==0" << endl;
  663. X      if (_f4) _f4();
  664. X      else cout << "_f4==0" << endl;
  665. X      if (_f5) cout << _f5(5, "Str1") << endl;
  666. X      else cout << "_f5==0" << endl;
  667. X      if (_f6) _f6(6, "Str2");
  668. X      else cout << "_f6==0" << endl;
  669. X      }
  670. X};
  671. X
  672. Xmain() {
  673. X   Model m;
  674. X   FP1 f;
  675. X   assert(!f);
  676. X   f = 0; assert(!f);
  677. X   f = functor(&m, &Model::enter1);
  678. X   assert(f);
  679. X   FP1 f2;
  680. X   f = f2; assert(f==0);
  681. X   f = functor(&m, &Model::enter1); assert(f);
  682. X   f = functor((Model*)0, &Model::enter1); assert(!f);
  683. X   f = functor(&m, (int(Model::*)(const char*))0); assert(!f);
  684. X   f = functor(&m, &Model::enter1); assert(f);
  685. X   f = functor((Model*)0, (int(Model::*)(const char*))0); assert(!f);
  686. X   FP1 f3(0);
  687. X   assert(!f3);
  688. X   View v(functor(&m, &Model::enter1), functorv(&m, &Model::enter2),
  689. X         functor(&m, &Model::save1), functorv(&m, &Model::save2),
  690. X         functor(&m, &Model::enterat1), functorv(&m, &Model::enterat2));
  691. X   v.input();
  692. X   View vz(FP1(0), FP2(0), FP3(0), FP4(0), FP5(0), FP6(0));
  693. X   vz.input();
  694. X   return 0;
  695. X}
  696. X
  697. END_OF_FILE
  698. if test 2354 -ne `wc -c <'tstftor.cpp'`; then
  699.     echo shar: \"'tstftor.cpp'\" unpacked with wrong size!
  700. fi
  701. # end of 'tstftor.cpp'
  702. fi
  703. echo shar: End of shell archive.
  704. exit 0
  705.