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

  1. /*-----------------------------------------------------------------------*
  2.  * filename - vnewvn.cpp
  3.  * C++ VECTOR_NEW for virtual base classes.
  4.  * Called internally by the compiler to allocate arrays of classes
  5.  *  having constructors
  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 near * _vector_vnew_(void near *ptr, // address of array, 0 means allocate
  24.                  size_t size,             // size of each object
  25.                  unsigned count,          // how many objects
  26.                  unsigned mode,           // actual type of constructor
  27.                  ...
  28.                  )
  29. /* This routine is used to initialize an array of class type.  If ptr is
  30.    NULL, it allocates the space for the array first.  Since the constructor
  31.    for the class may be of either memory model, and take an argument of any
  32.    memory model, we are forced to pass a mode parameter to tell us how to
  33.    cast it.  Since we must pass a near pointer for near functions and a
  34.    far call for far functions, we can't even know the argument type until
  35.    runtime, so we have to use varargs to get at it.  This version passes the
  36.    second argument needed for a class with virtual bases.
  37.  
  38.    If the constructor pointer is NULL no constructors are called.
  39.  
  40.    The interpretation of the mode parameter is:
  41.        far function    0x01     VFARCALL
  42.        pascal call     0x02     VPASCAL
  43.        far pointer     0x04     VFARPTR
  44.        deallocate      0x08     VDEALLOC
  45.        stored count    0x10     VSTORECNT
  46.        fastcall        0x20     VFASTCALL
  47.        huge vector     0x40     VHUGEVECT
  48.        fastthis        0x80     VFASTTHIS
  49.        this last       0x100    VTHISLAST
  50. */
  51. {
  52. #if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
  53.     abort();
  54.     return 0;
  55. #else
  56.     va_list ap;         // for access to parameters
  57.     consvNNC np;        // near call version
  58.     consvFNC fp;        // far call version
  59.     int construct = 1;  // flag whether to call constructors
  60.  
  61.     va_start(ap, mode);
  62.  
  63.     if (mode & VFARCALL)
  64.         {
  65.         fp = va_arg(ap, consvFNC);
  66.         if (!fp)
  67.             construct = 0;
  68.         }
  69.     else
  70.         {
  71.         np = va_arg(ap, consvNNC);
  72.         if (!np)
  73.             construct = 0;
  74.         }
  75.  
  76.     if( ptr == 0 )
  77.         {
  78.         unsigned long Length = size * count;
  79.  
  80.         if (mode & VSTORECNT)   // stored count
  81.             Length += sizeof(count);
  82.  
  83.         // check that additional bytes don't make it go over 64K
  84.         if (Length > 0xFFFF)
  85.             return 0;
  86.  
  87.         ptr = operator new((unsigned)Length);
  88.  
  89.         if (!ptr)
  90.             return 0;
  91.  
  92.         // have ptr at either final location or count before
  93.         if (mode & VSTORECNT)   // store count
  94.             {
  95.             *(unsigned *)ptr = count;
  96.             ((unsigned *)ptr)++;
  97.             }
  98.         }
  99.  
  100.     mode &= VCALLTYPE;   // strip out all flags except call type
  101.  
  102.     if (mode & VFASTTHIS)   // this-last has no effect with fast-this
  103.         mode &= ~(VTHISLAST);
  104.  
  105.     if (construct)
  106.         {
  107.         for( char *p = (char *) ptr;  count-- > 0;  p += size )
  108.             switch (mode)
  109.                 {
  110.                 case 0:
  111.                     (*(consvNNC) np)((void near *) p, 0); break;
  112.                 case (VFARCALL):
  113.                     (*(consvFNC) fp)((void near *) p, 0); break;
  114.                 case (VPASCAL):
  115.                     (*(consvNNP) np)((void near *) p, 0); break;
  116.                 case (VPASCAL | VTHISLAST):
  117.                     (*(consvNNPL) np)(0, (void near *) p); break;
  118.                 case (VFARCALL | VPASCAL):
  119.                     (*(consvFNP) fp)((void near *) p, 0); break;
  120.                 case (VFARCALL | VPASCAL | VTHISLAST):
  121.                     (*(consvFNPL) fp)(0, (void near *) p); break;
  122.                 case (VFASTCALL):
  123.                     (*(consvNNF) np)((void near *) p, 0); break;
  124.                 case (VFASTCALL | VTHISLAST):
  125.                     (*(consvNNFL) np)(0, (void near *) p); break;
  126.                 case (VFARCALL | VFASTCALL):
  127.                     (*(consvFNF) fp)((void near *) p, 0); break;
  128.                 case (VFARCALL | VFASTCALL | VTHISLAST):
  129.                     (*(consvFNFL) fp)(0, (void near *) p); break;
  130.                 case (0 | VFASTTHIS):
  131.                     LOAD_NEAR_THIS(p);
  132.                     (*(consvNNCT) np)(0);
  133.                     END_NEAR_THIS();
  134.                     break;
  135.                 case (VFARCALL | VFASTTHIS):
  136.                     LOAD_NEAR_THIS(p);
  137.                     (*(consvFNCT) fp)(0);
  138.                     END_NEAR_THIS();
  139.                     break;
  140.                 case (VPASCAL | VFASTTHIS):
  141.                     LOAD_NEAR_THIS(p);
  142.                     (*(consvNNPT) np)(0);
  143.                     END_NEAR_THIS();
  144.                     break;
  145.                 case (VFARCALL | VPASCAL | VFASTTHIS):
  146.                     LOAD_NEAR_THIS(p);
  147.                     (*(consvFNPT) fp)(0);
  148.                     END_NEAR_THIS();
  149.                     break;
  150.                 case (VFASTCALL | VFASTTHIS):
  151.                     LOAD_NEAR_THIS(p);
  152.                     (*(consvNNFT) np)(0);
  153.                     END_NEAR_THIS();
  154.                     break;
  155.                 case (VFARCALL | VFASTCALL | VFASTTHIS):
  156.                     LOAD_NEAR_THIS(p);
  157.                     (*(consvFNFT) fp)(0);
  158.                     END_NEAR_THIS();
  159.                     break;
  160.                 default:
  161.                     abort(); break;
  162.                 }
  163.         }
  164.     return ptr;
  165. #endif
  166. }
  167.