home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / progjour / 1990 / 05 / vint.cpp < prev    next >
C/C++ Source or Header  |  1990-08-06  |  7KB  |  189 lines

  1. #ifdef __TURBOC__
  2. #include <stdio.h>
  3. #include <iostream.h>
  4. #else
  5. #include <stream.hpp>
  6. #endif
  7.  
  8. #include <stdlib.h>
  9. #include "virt.hpp"
  10.  
  11. // VINT.CPP: Example of how to encapsulate the virtual memory functions in
  12. //virt.c into a C++ object. #include this file to get support for virtual 
  13. //int arrays. Compile with COMPILE_METHODS defined to create library-
  14. //support functions. Define MAIN to get a small test program.
  15. //  Declarations:
  16. //  vint x(100L);         Create a virtual array of 100 ints
  17. //  Valid operations:
  18. //  x[n]        This is a selector operator. The next operation
  19. //              controls what happens to that element. The
  20. //              following operations are supported (x is a vint
  21. //              and i is an int):
  22. //  i + x[n]      i - x[n]       i * x[n]       i / x[n]      i = x[n]
  23. //  x[n] + i      x[n] - i       x[n] * i       x[n] / i      x[n] = i
  24. //  x[n] + x[i]   x[n] - x[i]    x[n] * x[i]    x[n] / x[i]   x[n] = x[i]
  25. //  ++x[n]        --x[n]
  26. //  All of these operators evaluate to int rvalues, so
  27. //  (x[i] = x[j] = x[k]) doesn't work.
  28. //  x[n] by itself evaluates to a reference to a vint, not to an int. There
  29. //  is a vint-to-int conversion supplied so that you can use a reference
  30. //  directly, however.
  31. //  Something like x+i, with no index on the x, uses the most-recently-
  32. //  selected element. This syntax is weird--it's really a side effect of
  33. //  the select-then-operate strategy--so you shouldn't use it.
  34. //  Finally, note that an long-to-vint conversion is supplied by because of
  35. //  the constructor syntax. This conversion doesn't do what you think (it
  36. //  creates an empty array of the size specified in the conversion).
  37. //  Be careful.
  38. class vint {
  39. private:
  40.     static int nobj;            // number of active objects
  41.     void       *hdr;            // virtual-memory handle
  42.     int        *cur_ele;        // Most recently selected object.
  43.     long       cur_index;       // index of "
  44.  
  45.     friend int val( vint &v );
  46.  
  47. public:
  48.                  vint          ( long array_size );
  49.                  ~vint         ();
  50.                  vint          ( vint &hdr );
  51.                  operator int  ();
  52.            vint &operator []   ( long index );
  53.            int   operator +    ( /* this, */ int i   );
  54.            int   operator -    ( /* this, */ int i   );
  55.            int   operator *    ( /* this, */ int i   );
  56.            int   operator /    ( /* this, */ int i   );
  57.            int   operator =    ( /* this, */ int i   );
  58.            int   operator =    ( /* this, */ vint &v );
  59.            int   operator ++   ( /* this, */         );
  60.            int   operator --   ( /* this, */         );
  61.     friend int   operator +    ( int i,      vint &r );
  62.     friend int   operator -    ( int i,      vint &r );
  63.     friend int   operator *    ( int i,      vint &r );
  64.     friend int   operator /    ( int i,      vint &r );
  65.     friend int   operator +    ( vint &l,    vint &r );
  66.     friend int   operator -    ( vint &l,    vint &r );
  67.     friend int   operator *    ( vint &l,    vint &r );
  68.     friend int   operator /    ( vint &l,    vint &r );
  69. };
  70.  
  71. #ifdef COMPILE_METHODS
  72. //constructor, starts up the virtual-memory system the first time it's
  73. //called. Allocates a new array.
  74.  
  75. vint::vint( long array_size ) : cur_ele(NULL), cur_index(0) {
  76.     if ( nobj++ == 0 )
  77.         vopen();        // initialize the virtual-memory system
  78.   
  79.     if ( !(hdr = vmalloc(array_size, sizeof(int))) ) {
  80.         perror( "VMS allocation error" );
  81.         exit( 1 );
  82.     }
  83. }
  84.  
  85. vint::~vint() { // destructor, frees current object and if no more objects
  86.     if ( !vfree( hdr ) ) {   // are left, shuts down virtual-memory system
  87.         perror( "VMS deallocation error" );
  88.         exit( 1 );
  89.     }
  90.     if ( --nobj == 0 )
  91.         vclose();           // close down the virtual-memory system
  92. }
  93.  
  94. vint::vint( vint &src ) : cur_ele(NULL), cur_index(0) {
  95. // Copy constructor. VERY expensive operation. duplicates array in src.
  96.     int  *p;
  97.     long numele = vele( src.hdr );
  98.  
  99.     if ( nobj++ == 0 )
  100.         vopen();            // initialize the virtual-memory system
  101.  
  102.     if ( hdr && !vfree( hdr ) ) {
  103.         perror( "VMS copy-deallocation error" );
  104.         exit( 1 );
  105.     }
  106.  
  107.     if ( !(hdr = vmalloc( numele, sizeof(int))) ) {
  108.         perror( "VMS copy-allocation error" );
  109.         exit( 1 );
  110.     }
  111.    
  112.     while ( --numele >= 0 ) {
  113.         if ( !(p = (int *)vread( src.hdr, numele )) ) {
  114.             perror ( "VMS copy-access (read) error." );
  115.             exit( 1 );
  116.         }
  117.    
  118.         if ( !vwrite( hdr, numele, p ) ) {
  119.             perror( "VMS copy-access (write) error.\n" );
  120.             exit( 1 );
  121.         }
  122.     }
  123. }
  124.  
  125. vint::operator int()
  126. {      // convert vint to int
  127.     if ( cur_ele )
  128.         return *cur_ele;
  129.  
  130.     cerr << "VMS: no previous index on vint.\n";
  131.     return 0;
  132. }
  133.  
  134. vint &vint::operator []( long index ) {  // select an array member
  135.     if ( !(cur_ele = (int *)vread( hdr, index )) )
  136.         perror( "VMS selection error" );
  137.      
  138.     cur_index = index;
  139.     return *this;
  140. }
  141. // The following methods all modify the member that was selected by a 
  142. // previous array-index ([i]) operator. Note that there's no provision for
  143. // a vint=vint operator because the earlier vint-to-int conversion will act
  144. // on the right argument to make it suitable for the vint=int operator 
  145. // defined below.
  146. /* static */ int val( vint &v ) { // return the value of the currently-
  147.     if ( v.cur_ele )        // selected member.
  148.         return *v.cur_ele ;
  149.    
  150.     cerr << "VMS: No previous index on vint (val)\n" ;
  151.     return 0;
  152. }
  153. int vint::operator ++ () {  // increment the current member
  154.     val(*this);             // val call for error checking.
  155.     vdirty(hdr);
  156.     return ++*cur_ele;
  157. }
  158. int vint::operator -- () {  // decrement the current member
  159.     val(*this);             // val call for error checking.
  160.     vdirty(hdr);
  161.     return --*cur_ele;
  162. }
  163. int vint::operator = ( int i ) { // assign to the current member
  164.     if ( !cur_ele ) {
  165.         cerr << "VMS: No array index on a vint (=)\n" ;
  166.         return 0;
  167.     }
  168.     vdirty( hdr );
  169.     return *cur_ele = i;
  170. }
  171. #endif /* COMPILE_METHODS */
  172.  
  173. // These functions take care of the nondestructive arithmetic
  174. // operations. The ones with two arguments are friends of class vint.
  175. inline int vint::operator +    ( int i ){ return  val(*this) + i; }
  176. inline int vint::operator -    ( int i ){ return  val(*this) - i; }
  177. inline int vint::operator *    ( int i ){ return  val(*this) * i; }
  178. inline int vint::operator /    ( int i ){ return  val(*this) / i; }
  179.       
  180. inline int operator + (int i,   vint &r){ return  i      + val(r); }
  181. inline int operator - (int i,   vint &r){ return  i      - val(r); }
  182. inline int operator * (int i,   vint &r){ return  i      * val(r); }
  183. inline int operator / (int i,   vint &r){ return  i      / val(r); }
  184.         
  185. inline int operator + (vint &l, vint &r){ return  val(l) + val(r); }
  186. inline int operator - (vint &l, vint &r){ return  val(l) - val(r); }
  187. inline int operator * (vint &l, vint &r){ return  val(l) * val(r); }
  188. inline int operator / (vint &l, vint &r){ return  val(l) / val(r); } 
  189.