home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 5.ddi / CLIBSRC2.ZIP / VDELN.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  5.4 KB  |  159 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 <_vector.h>
  20.  
  21. #pragma argsused
  22.  
  23. void _vector_delete_(void near *ptr,    // address of array (always needed)
  24.              size_t size,               // size of each object
  25.              unsigned count,            // how many objects
  26.              unsigned mode,             // How to call
  27.              ...
  28.             )
  29. /* This routine is used to destroy an array of class type.  If mode is
  30.    set, it deallocates the space for the array afterwards. Since the
  31.    destructor for the class may be of either memory model, and take
  32.    an argument of any memory model, we are forced to pass a mode parameter
  33.    to tell us how to cast it.  Since we must pass a near pointer for near
  34.    functions and a far pointer for far functions, we can't even know the
  35.    argument type until runtime, so we have to use varargs to get at it.
  36.  
  37.    If the destructor pointer is NULL no destructors are called.
  38.  
  39.    The interpretation of the mode parameter is:
  40.        far function    0x01     VFARCALL
  41.        pascal call     0x02     VPASCAL
  42.        far pointer     0x04     VFARPTR
  43.        deallocate      0x08     VDEALLOC
  44.        stored count    0x10     VSTORECNT
  45.        fastcall        0x20     VFASTCALL
  46.        huge vector     0x40     VHUGEVECT
  47.        fastthis        0x80     VFASTTHIS
  48.        this last       0x100    VTHISLAST
  49. */
  50. {
  51. #if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
  52.     abort();
  53. #else
  54.     va_list ap;         // for access to parameters
  55.     destNNC np;         // near call version
  56.     destFNC fp;         // far call version
  57.     int destruct = 1;   // flag whether to call destructors
  58.  
  59.     if (!ptr)
  60.         return;
  61.  
  62.     va_start(ap, mode);
  63.  
  64.     if (mode & VFARCALL)
  65.         {
  66.         fp = va_arg(ap, destFNC);
  67.         if (!fp)
  68.             destruct = 0;
  69.         }
  70.     else
  71.         {
  72.         np = va_arg(ap, destNNC);
  73.         if (!np)
  74.             destruct = 0;
  75.         }
  76.  
  77.     if (mode & VSTORECNT)   // if stored count
  78.         count = *((unsigned *) ((char *)ptr - sizeof(count)));
  79.  
  80.     if (destruct)
  81.         {
  82.         // get call type
  83.         unsigned CallType = mode & VCALLTYPE;
  84.  
  85.         // this-last has no effect with fast-this
  86.         if (CallType & VFASTTHIS)
  87.             CallType &= ~(VTHISLAST);
  88.  
  89.         for(char near *p = (char near *) ptr + size * (count - 1);
  90.             count-- > 0; p -= size)
  91.             {
  92.             switch (CallType)
  93.                 {
  94.                 case 0:
  95.                     (*(destNNC) np)((void near *) p, 2); break;
  96.                 case (VFARCALL):
  97.                     (*(destFNC) fp)((void near *) p, 2); break;
  98.                 case (VPASCAL):
  99.                     (*(destNNP) np)((void near *) p, 2); break;
  100.                 case (VPASCAL | VTHISLAST):
  101.                     (*(destNNPL) np)(2, (void near *) p); break;
  102.                 case (VFARCALL | VPASCAL):
  103.                     (*(destFNP) fp)((void near *) p, 2); break;
  104.                 case (VFARCALL | VPASCAL | VTHISLAST):
  105.                     (*(destFNPL) fp)(2, (void near *) p); break;
  106.                 case (VFASTCALL):
  107.                     (*(destNNF) np)((void near *) p, 2); break;
  108.                 case (VFASTCALL | VTHISLAST):
  109.                     (*(destNNFL) np)(2, (void near *) p); break;
  110.                 case (VFARCALL | VFASTCALL):
  111.                     (*(destFNF) fp)((void near *) p, 2); break;
  112.                 case (VFARCALL | VFASTCALL | VTHISLAST):
  113.                     (*(destFNFL) fp)(2, (void near *) p); break;
  114.                 case (0 | VFASTTHIS):
  115.                     LOAD_NEAR_THIS(p);
  116.                     (*(destNNCT) np)(2);
  117.                     END_NEAR_THIS();
  118.                     break;
  119.                 case (VFARCALL | VFASTTHIS):
  120.                     LOAD_NEAR_THIS(p);
  121.                     (*(destFNCT) fp)(2);
  122.                     END_NEAR_THIS();
  123.                     break;
  124.                 case (VPASCAL | VFASTTHIS):
  125.                     LOAD_NEAR_THIS(p);
  126.                     (*(destNNPT) np)(2);
  127.                     END_NEAR_THIS();
  128.                     break;
  129.                 case (VFARCALL | VPASCAL | VFASTTHIS):
  130.                     LOAD_NEAR_THIS(p);
  131.                     (*(destFNPT) fp)(2);
  132.                     END_NEAR_THIS();
  133.                     break;
  134.                 case (VFASTCALL | VFASTTHIS):
  135.                     LOAD_NEAR_THIS(p);
  136.                     (*(destNNFT) np)(2);
  137.                     END_NEAR_THIS();
  138.                     break;
  139.                 case (VFARCALL | VFASTCALL | VFASTTHIS):
  140.                     LOAD_NEAR_THIS(p);
  141.                     (*(destFNFT) fp)(2);
  142.                     END_NEAR_THIS();
  143.                     break;
  144.                 default:
  145.                     abort(); break;
  146.                 }
  147.             }
  148.         }
  149.  
  150.     if (mode & VDEALLOC)
  151.         {
  152.         if (mode & VSTORECNT)   // stored count
  153.             ptr = (char *)ptr - sizeof(count);
  154.  
  155.         operator delete((void near *)ptr);
  156.         }
  157. #endif
  158. }
  159.