home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 5.ddi / CLIBSRC2.ZIP / CASTMPTR.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  3.1 KB  |  119 lines

  1. /*-----------------------------------------------------------------------*
  2.  * filename - castmptr.cpp
  3.  *-----------------------------------------------------------------------*/
  4.  
  5. /*
  6.  *      C/C++ Run Time Library - Version 5.0
  7.  *
  8.  *      Copyright (c) 1990, 1992 by Borland International
  9.  *      All Rights Reserved.
  10.  *
  11.  */
  12.  
  13.  
  14. #include <_defs.h>
  15.  
  16. typedef unsigned    addr_t;
  17.  
  18. typedef struct
  19. {
  20.     addr_t      thisAdj;
  21.     addr_t      VBPoffs;
  22. }
  23.     mptr;
  24.  
  25. /******************************************************************************
  26.  *
  27.  *  This routine is used for casts of member pointers that may
  28.  *  point to members of virtual base classes. The parameters
  29.  *  are as follows:
  30.  *
  31.  *      mp  -   address of the "thisAdj" member
  32.  *              of the member pointer being cast
  33.  *
  34.  *      tp  -   address of the compiler-generated
  35.  *              conversion table
  36.  *
  37.  *       mptrSize   -   size of the member pointer type
  38.  *
  39.  *       ThisAdj    -   change in "thisAdj" due to the cast
  40.  *
  41.  *       VBPoffs    -   new value for "VBPoffs" or 0
  42.  *
  43.  *  The result of calling this routine is that either the member
  44.  *  pointer value is converted to the new type, or it is set to
  45.  *  0 if the cast cannot be carried out (see the -Vv compiler
  46.  *  switch for details).
  47.  */
  48.  
  49. void    _FARFUNC _cast_memptr(void far *    mp,
  50.              void far * tp, addr_t mptrSize,
  51.                              addr_t thisAdj,
  52.                              addr_t VBPoffs)
  53. {
  54.     mptr    far *   mpp = (mptr far *)mp;
  55.  
  56.     if  (VBPoffs)
  57.     {
  58.         /* Does the current value point to a vbase member? */
  59.  
  60.         if  (mpp->VBPoffs)
  61.         {
  62.             addr_t  far *   tbl = (addr_t far *)tp;
  63.             char    far *   pp;
  64.  
  65.             /* Look for a matching virtual base in the table */
  66.  
  67.             for (;;)
  68.             {
  69.                 addr_t      srcOffs;
  70.  
  71.                 srcOffs = *tbl++;
  72.                 if  (srcOffs == 0)
  73.                     break;
  74.  
  75.                 if  (srcOffs == mpp->VBPoffs)
  76.                 {
  77.                     /* Found a match, update value */
  78.  
  79.                     mpp->VBPoffs  = *tbl;
  80.                     return;
  81.                 }
  82.  
  83.                 /* Skip the 'new' offset value and continue */
  84.  
  85.                 tbl++;
  86.             }
  87.  
  88.             /* Here we have an illegal cast: set mptr to NULL */
  89.  
  90.             pp = (char far *)mp + 2 * sizeof(addr_t) - mptrSize;
  91.  
  92.             /* Note: the following might better be done through
  93.                  memset, but in the small data models a 'far'
  94.                  memset is not available, as far as I know.
  95.              */
  96.  
  97.             do
  98.             {
  99.                 *pp++ = 0;
  100.             }
  101.             while   (--mptrSize);
  102.         }
  103.         else
  104.         {
  105.             mpp->thisAdj += thisAdj;
  106.             mpp->VBPoffs  = VBPoffs;
  107.         }
  108.     }
  109.     else
  110.     {
  111.         /* This part might be generated inline by the compiler */
  112.  
  113.         if  (mpp->VBPoffs)
  114.             mpp->VBPoffs += thisAdj;
  115.         else
  116.             mpp->thisAdj += thisAdj;
  117.     }
  118. }
  119.