home *** CD-ROM | disk | FTP | other *** search
- /*-----------------------------------------------------------------------*
- * filename - vapp.cpp
- * C++ VECTOR APPLY
- * This is called internally by the compiler to copy arrays of classes
- * having assignment operators or reference constructors
- *-----------------------------------------------------------------------*/
-
- /*
- * C/C++ Run Time Library - Version 5.0
- *
- * Copyright (c) 1990, 1992 by Borland International
- * All Rights Reserved.
- *
- */
-
-
- #include <stdarg.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include <_vector.h>
-
- extern "C"
- void _vector_apply_(void far* dest, // address of destination array
- void far* src, // address of source array
- size_t size, // size of each object
- unsigned count, // number of objects
- unsigned mode,
- ...
- )
-
- /* This routine is used to copy an array of class type.
-
- Since the routine used for the class may be of either memory model, and
- take arguments of any memory model, we are forced to pass a mode
- parameter to tell us how to cast it. Since we must pass a near pointer
- for near functions and a far call for far functions, we can't even know
- the argument type until runtime, so we have to use varargs to get at it.
- We do assume that both source and destination have the same distance
- modifier, and the compiler enforces that.
-
- The interpretation of the mode parameter is:
- far function 0x01 VFARCALL
- pascal call 0x02 VPASCAL
- far pointer 0x04 VFARPTR
- fastcall 0x20 VFASTCALL
- fastthis 0x80 VFASTTHIS
- this last 0x100 VTHISLAST
- */
- {
- va_list ap; /* for access to parameters */
- appNNC np; /* Near pointer version */
- appFNC fp; /* Far pointer version */
-
- va_start(ap, mode);
-
- if (mode & VFARCALL)
- fp = va_arg(ap, appFNC);
- else
- np = va_arg(ap, appNNC);
-
- if (mode & VFASTTHIS) // this-last has no effect with fast-this
- mode &= ~(VTHISLAST);
-
- do
- {
- switch (mode)
- {
- case 0:
- (*(appNNC) np)((void near *)dest, (void near *)src); break;
- case (VFARCALL):
- (*(appFNC) fp)((void near *)dest, (void near *)src); break;
- case (VPASCAL):
- (*(appNNP) np)((void near *)dest, (void near *)src); break;
- case (VPASCAL | VTHISLAST):
- (*(appNNPL) np)((void near *)src, (void near *)dest); break;
- case (VFARCALL | VPASCAL):
- (*(appFNP) fp)((void near *)dest, (void near *)src); break;
- case (VFARCALL | VPASCAL | VTHISLAST):
- (*(appFNPL) fp)((void near *)src, (void near *)dest); break;
- case (VFASTCALL):
- (*(appNNF) np)((void near *)dest, (void near *)src); break;
- case (VFASTCALL | VTHISLAST):
- (*(appNNFL) np)((void near *)src, (void near *)dest); break;
- case (VFARCALL | VFASTCALL):
- (*(appFNF) fp)((void near *)dest, (void near *)src); break;
- case (VFARCALL | VFASTCALL | VTHISLAST):
- (*(appFNFL) fp)((void near *)src, (void near *)dest); break;
- case (VFARPTR):
- (*(appNFC) np)((void far *)dest, (void far *)src); break;
- case (VFARCALL | VFARPTR):
- (*(appFFC) fp)((void far *)dest, (void far *)src); break;
- case (VFARPTR | VPASCAL):
- (*(appNFP) np)((void far *)dest, (void far *)src); break;
- case (VFARPTR | VPASCAL | VTHISLAST):
- (*(appNFPL) np)((void far *)src, (void far *)dest); break;
- case (VFARCALL | VFARPTR | VPASCAL):
- (*(appFFP) fp)((void far *)dest, (void far *)src); break;
- case (VFARCALL | VFARPTR | VPASCAL | VTHISLAST):
- (*(appFFPL) fp)((void far *)src, (void far *)dest); break;
- case (VFARPTR | VFASTCALL):
- (*(appNFF) np)((void far *)dest, (void far *)src); break;
- case (VFARPTR | VFASTCALL | VTHISLAST):
- (*(appNFFL) np)((void far *)src, (void far *)dest); break;
- case (VFARCALL | VFARPTR | VFASTCALL):
- (*(appFFF) fp)((void far *)dest, (void far *)src); break;
- case (VFARCALL | VFARPTR | VFASTCALL | VTHISLAST):
- (*(appFFFL) fp)((void far *)src, (void far *)dest); break;
- case (0 | VFASTTHIS):
- LOAD_NEAR_THIS(dest);
- (*(appNNCT) np)((void near *)src);
- END_NEAR_THIS();
- break;
- case (VFARCALL | VFASTTHIS):
- LOAD_NEAR_THIS(dest);
- (*(appFNCT) fp)((void near *)src);
- END_NEAR_THIS();
- break;
- case (VPASCAL | VFASTTHIS):
- LOAD_NEAR_THIS(dest);
- (*(appNNPT) np)((void near *)src);
- END_NEAR_THIS();
- break;
- case (VFARCALL | VPASCAL | VFASTTHIS):
- LOAD_NEAR_THIS(dest);
- (*(appFNPT) fp)((void near *)src);
- END_NEAR_THIS();
- break;
- case (VFASTCALL | VFASTTHIS):
- LOAD_NEAR_THIS(dest);
- (*(appNNFT) np)((void near *)src);
- END_NEAR_THIS();
- break;
- case (VFARCALL | VFASTCALL | VFASTTHIS):
- LOAD_NEAR_THIS(dest);
- (*(appFNFT) fp)((void near *)src);
- END_NEAR_THIS();
- break;
- case (VFARPTR | VFASTTHIS):
- LOAD_FAR_THIS(dest);
- (*(appNFCT) np)((void far *)src);
- END_FAR_THIS();
- break;
- case (VFARCALL | VFARPTR | VFASTTHIS):
- LOAD_FAR_THIS(dest);
- (*(appFFCT) fp)((void far *)src);
- END_FAR_THIS();
- break;
- case (VFARPTR | VPASCAL | VFASTTHIS):
- LOAD_FAR_THIS(dest);
- (*(appNFPT) np)((void far *)src);
- END_FAR_THIS();
- break;
- case (VFARCALL | VFARPTR | VPASCAL | VFASTTHIS):
- LOAD_FAR_THIS(dest);
- (*(appFFPT) fp)((void far *)src);
- END_FAR_THIS();
- break;
- case (VFARPTR | VFASTCALL | VFASTTHIS):
- LOAD_FAR_THIS(dest);
- (*(appNFFT) np)((void far *)src);
- END_FAR_THIS();
- break;
- case (VFARCALL | VFARPTR | VFASTCALL | VFASTTHIS):
- LOAD_FAR_THIS(dest);
- (*(appFFFT) fp)((void far *)src);
- END_FAR_THIS();
- break;
- default:
- abort(); break;
- }
- (char far *) dest += size;
- (char far *) src += size;
- } while (--count > 0);
- }
-