home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 2.ddi / CLIBSRC3.ZIP / VDELF.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  5.7 KB  |  165 lines

  1. /*-----------------------------------------------------------------------*
  2.  * filename - vdel.cpp
  3.  * C++ vector_delete
  4.  * Called internally by the compiler to deallocate arrays of classes
  5.  * having destructors
  6.  *-----------------------------------------------------------------------*/
  7.  
  8. /*
  9.  *      C/C++ Run Time Library - Version 5.0
  10.  *
  11.  *      Copyright (c) 1990, 1992 by Borland International
  12.  *      All Rights Reserved.
  13.  *
  14.  */
  15.  
  16.  
  17. #include <stdlib.h>
  18. #include <stdarg.h>
  19. #include <dos.h>
  20. #include <_vector.h>
  21.  
  22. void _vector_delete_(void far *ptr,     // address of array (always needed)
  23.              size_t size,               // size of each object
  24.              unsigned long count,       // how many objects
  25.              unsigned mode,             // How to call
  26.              ...
  27.             )
  28. /* This routine is used to destroy an array of class type.  If mode is
  29.    set, it deallocates the space for the array afterwards. Since the
  30.    destructor for the class may be of either memory model, and take
  31.    an argument of any memory model, we are forced to pass a mode parameter
  32.    to tell us how to cast it.  Since we must pass a near pointer for near
  33.    functions and a far pointer for far functions, we can't even know the
  34.    argument type until runtime, so we have to use varargs to get at it.
  35.  
  36.    If the destructor pointer is NULL no destructors are called.
  37.  
  38.    The interpretation of the mode parameter is:
  39.        far function    0x01     VFARCALL
  40.        pascal call     0x02     VPASCAL
  41.        far pointer     0x04     VFARPTR
  42.        deallocate      0x08     VDEALLOC
  43.        stored count    0x10     VSTORECNT
  44.        fastcall        0x20     VFASTCALL
  45.        huge vector     0x40     VHUGEVECT
  46.        fastthis        0x80     VFASTTHIS
  47.        this last       0x100    VTHISLAST
  48. */
  49. {
  50.     va_list ap;         // for access to parameters
  51.     destNNC np;         // near call version
  52.     destFNC fp;         // far call version
  53.     int destruct = 1;   // flag whether to call destructors
  54.  
  55.     if (!ptr)
  56.         return;
  57.  
  58.     va_start(ap, mode);
  59.  
  60.     if (mode & VFARCALL)
  61.         {
  62.         fp = va_arg(ap, destFNC);
  63.         if (!fp)
  64.             destruct = 0;
  65.         }
  66.     else
  67.         {
  68.         np = va_arg(ap, destNNC);
  69.         if (!np)
  70.             destruct = 0;
  71.         }
  72.  
  73.     if (mode & VSTORECNT)       // if stored count
  74.         count = *((unsigned long far *) ((char far *)ptr - sizeof(count)));
  75.  
  76.     if (destruct)
  77.         {
  78.         // get call type
  79.         unsigned CallType = mode & VCALLTYPE;
  80.  
  81.         if (CallType & VFASTTHIS)
  82.             CallType &= ~(VTHISLAST);
  83.  
  84.         for( char huge *p = (char huge *) ptr + size * (count - 1);
  85.              count-- > 0; p -= size )
  86.             {
  87.             switch (CallType)
  88.                 {
  89.                 case (VFARPTR):
  90.                     (*(destNFC) np)((void far  *) p, 2); break;
  91.                 case (VFARCALL | VFARPTR):
  92.                     (*(destFFC) fp)((void far  *) p, 2); break;
  93.                 case (VFARPTR | VPASCAL):
  94.                     (*(destNFP) np)((void far  *) p, 2); break;
  95.                 case (VFARPTR | VPASCAL | VTHISLAST):
  96.                     (*(destNFPL) np)(2, (void far  *) p); break;
  97.                 case (VFARCALL | VFARPTR | VPASCAL):
  98.                     (*(destFFP) fp)((void far  *) p, 2); break;
  99.                 case (VFARCALL | VFARPTR | VPASCAL | VTHISLAST):
  100.                     (*(destFFPL) fp)(2, (void far  *) p); break;
  101.                 case (VFARPTR | VFASTCALL):
  102.                     (*(destNFF) np)((void far  *) p, 2); break;
  103.                 case (VFARPTR | VFASTCALL | VTHISLAST):
  104.                     (*(destNFFL) np)(2, (void far  *) p); break;
  105.                 case (VFARCALL | VFARPTR | VFASTCALL):
  106.                     (*(destFFF) fp)((void far  *) p, 2); break;
  107.                 case (VFARCALL | VFARPTR | VFASTCALL | VTHISLAST):
  108.                     (*(destFFFL) fp)(2, (void far  *) p); break;
  109.                 case (VFARPTR | VFASTTHIS):
  110.                     LOAD_FAR_THIS(p);
  111.                     (*(destNFCT) np)(2);
  112.                     END_FAR_THIS();
  113.                     break;
  114.                 case (VFARCALL | VFARPTR | VFASTTHIS):
  115.                     LOAD_FAR_THIS(p);
  116.                     (*(destFFCT) fp)(2);
  117.                     END_FAR_THIS();
  118.                     break;
  119.                  case (VFARPTR | VPASCAL | VFASTTHIS):
  120.                     LOAD_FAR_THIS(p);
  121.                     (*(destNFPT) np)(2);
  122.                     END_FAR_THIS();
  123.                     break;
  124.                 case (VFARCALL | VFARPTR | VPASCAL | VFASTTHIS):
  125.                     LOAD_FAR_THIS(p);
  126.                     (*(destFFPT) fp)(2);
  127.                     END_FAR_THIS();
  128.                     break;
  129.                  case (VFARPTR | VFASTCALL | VFASTTHIS):
  130.                     LOAD_FAR_THIS(p);
  131.                     (*(destNFFT) np)(2);
  132.                     END_FAR_THIS();
  133.                     break;
  134.                 case (VFARCALL | VFARPTR | VFASTCALL | VFASTTHIS):
  135.                     LOAD_FAR_THIS(p);
  136.                     (*(destFFFT) fp)(2);
  137.                     END_FAR_THIS();
  138.                     break;
  139.                 default:
  140.                     abort(); break;
  141.                 }
  142.             }
  143.         }
  144.  
  145.     if (mode & VDEALLOC)
  146.         {
  147.         unsigned Header;
  148.         unsigned Overhead = 0;
  149.  
  150.         if (mode & 0x10)        // stored count
  151.             Overhead = sizeof(count);
  152.  
  153.         if (mode & VHUGEVECT)   // huge vector
  154.             {
  155.             Overhead += sizeof(Header);
  156.             Header = *((char far *)ptr - Overhead);
  157.             ptr = MK_FP(FP_SEG(ptr), Header);
  158.             }
  159.         else
  160.             ptr = (char far *)ptr - Overhead;
  161.  
  162.         operator delete((void far *)ptr);
  163.         }
  164. }
  165.