IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 29, 2006, 4:20:43 PM (20 years ago)
Author:
Paul Price
Message:

Moved PS_ASSERT functions into appropriate places. Created psAssert.h for general PS_ASSERT functions. Vector-specific assertions went to psVector.h; image-specific assertions went to psImage.h, etc. psConstants.h remains, but only contains specific math constants and functions, as the name implies.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/math/psConstants.h

    r7765 r7766  
    66 *  @author GLG, MHPCC
    77 *
    8  *  @version $Revision: 1.92 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2006-06-30 01:57:46 $
     8 *  @version $Revision: 1.93 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2006-06-30 02:20:06 $
    1010 *
    1111 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    4545
    4646/*****************************************************************************
    47  
    48 *****************************************************************************/
    49 
    50 #define PS_ASSERT_INT_UNEQUAL(NAME1, NAME2, RVAL) \
    51 if ((NAME1) == (NAME2)) { \
    52     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    53             "Error: %s and %s are equal.", \
    54             #NAME1, #NAME2); \
    55     return(RVAL); \
    56 }
    57 
    58 #define PS_ASSERT_INT_EQUAL(NAME1, NAME2, RVAL) \
    59 if ((NAME1) != (NAME2)) { \
    60     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    61             "Error: %s and %s are not equal.", \
    62             #NAME1, #NAME2); \
    63     return(RVAL); \
    64 }
    65 
    66 #define PS_ASSERT_INT_NONNEGATIVE(NAME, RVAL) \
    67 if ((NAME) < 0) { \
    68     psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Error: %s is less than 0.", #NAME); \
    69     return(RVAL); \
    70 }
    71 
    72 #define PS_ASSERT_INT_POSITIVE(NAME, RVAL) \
    73 if ((NAME) < 1) { \
    74     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    75             "Error: %s is 0 or less.", #NAME); \
    76     return(RVAL); \
    77 }
    78 
    79 #define PS_ASSERT_INT_ZERO(NAME, RVAL) \
    80 if ((NAME) != 0) { \
    81     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    82             "Error: %s is 0.", #NAME); \
    83     return(RVAL); \
    84 }
    85 
    86 #define PS_ASSERT_INT_NONZERO(NAME, RVAL) \
    87 if ((NAME) == 0) { \
    88     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    89             "Error: %s is 0.", #NAME); \
    90     return(RVAL); \
    91 }
    92 
    93 // XXX: Where did these int casts come from?
    94 #define PS_ASSERT_INT_WITHIN_RANGE(NAME, LOWER, UPPER, RVAL) \
    95 if ((int)(NAME) < LOWER || (int)(NAME) > UPPER) { \
    96     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    97             "Error: %s, %d, is out of range.  Must be between %d and %d.", \
    98             #NAME,(int)NAME,LOWER,UPPER); \
    99     return RVAL; \
    100 }
    101 
    102 #define PS_ASSERT_INT_LESS_THAN(VAR1, VAR2, RVAL) \
    103 if (!(VAR1 < VAR2)) { \
    104     psError(PS_ERR_UNKNOWN, true, \
    105             "Error: %s is not less than %s (%d, %d)", #VAR1, #VAR2, VAR1, VAR2); \
    106     return(RVAL); \
    107 }
    108 
    109 #define PS_ASSERT_INT_LESS_THAN_OR_EQUAL(VAR1, VAR2, RVAL) \
    110 if (!(VAR1 <= VAR2)) { \
    111     psError(PS_ERR_UNKNOWN, true, \
    112             "Error: %s is not less than %s (%d, %d)", #VAR1, #VAR2, VAR1, VAR2); \
    113     return(RVAL); \
    114 }
    115 
    116 #define PS_ASSERT_INT_LARGER_THAN(NAME1, NAME2, RVAL) \
    117 if (!((NAME1) > (NAME2))) { \
    118     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    119             "Error: !(%s > %s) (%d %d).", \
    120             #NAME1, #NAME2, NAME1, NAME2); \
    121     return(RVAL); \
    122 }
    123 
    124 #define PS_ASSERT_INT_LARGER_THAN_OR_EQUAL(NAME1, NAME2, RVAL) \
    125 if (!((NAME1) >= (NAME2))) { \
    126     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    127             "Error: !(%s >= %s) (%d %d).", \
    128             #NAME1, #NAME2, NAME1, NAME2); \
    129     return(RVAL); \
    130 }
    131 #define PS_ASSERT_FLOAT_LARGER_THAN(NAME1, NAME2, RVAL) \
    132 if (!((NAME1) > (NAME2))) { \
    133     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    134             "Error: !(%s > %s) (%f %f).", \
    135             #NAME1, #NAME2, NAME1, NAME2); \
    136     return(RVAL); \
    137 }
    138 
    139 #define PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(NAME1, NAME2, RVAL) \
    140 if (!((NAME1) >= (NAME2))) { \
    141     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    142             "Error: !(%s >= %s) (%f %f).", \
    143             #NAME1, #NAME2, NAME1, NAME2); \
    144     return(RVAL); \
    145 }
    146 
    147 #define PS_ASSERT_FLOAT_LESS_THAN(NAME1, NAME2, RVAL) \
    148 if (!((NAME1) < (NAME2))) { \
    149     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    150             "Error: !(%s < %s) (%f %f).", \
    151             #NAME1, #NAME2, NAME1, NAME2); \
    152     return(RVAL); \
    153 }
    154 
    155 #define PS_ASSERT_FLOAT_LESS_THAN_OR_EQUAL(NAME1, NAME2, RVAL) \
    156 if (!((NAME1) <= (NAME2))) { \
    157     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    158             "Error: !(%s <= %s) (%f %f).", \
    159             #NAME1, #NAME2, NAME1, NAME2); \
    160     return(RVAL); \
    161 }
    162 
    163 #define PS_ASSERT_FLOAT_NON_EQUAL(NAME1, NAME2, RVAL) \
    164 if (fabs((NAME2) - (NAME1)) < FLT_EPSILON) { \
    165     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    166             "Error: %s and %s are equal.", \
    167             #NAME1, #NAME2); \
    168     return(RVAL); \
    169 }
    170 
    171 #define PS_ASSERT_FLOAT_EQUAL(NAME1, NAME2, RVAL) \
    172 if (fabs((NAME2) - (NAME1)) > FLT_EPSILON) { \
    173     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    174             "Error: %s and %s are not equal.", \
    175             #NAME1, #NAME2); \
    176     return(RVAL); \
    177 }
    178 
    179 // Return an error if the arg lies outside the supplied range.
    180 #define PS_ASSERT_FLOAT_WITHIN_RANGE(NAME, LOWER, UPPER, RVAL) \
    181 if ((NAME) < (LOWER) || (NAME) > (UPPER)) { \
    182     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    183             "Error: %s, %f, is out of range.  Must be between %f and %f.", \
    184             #NAME, NAME, LOWER, UPPER); \
    185     return RVAL; \
    186 }
    187 
    188 #define PS_ASSERT_DOUBLE_WITHIN_RANGE(NAME, LOWER, UPPER, RVAL) \
    189 if ((NAME) < (LOWER) || (NAME) > (UPPER)) { \
    190     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    191             "Error: %s, %lf, is out of range.  Must be between %lf and %lf.", \
    192             #NAME, NAME, LOWER, UPPER); \
    193     return RVAL; \
    194 }
    195 
    196 #define PS_ASSERT_LONG_WITHIN_RANGE(NAME, LOWER, UPPER, RVAL) \
    197 if ((NAME) < (LOWER) || (NAME) > (UPPER)) { \
    198     psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
    199             "Error: %s, %lld, is out of range.", \
    200             #NAME, NAME, LOWER, UPPER); \
    201     return RVAL; \
    202 }
    203 
    204 /*****************************************************************************
    205 Macros which take a generic psLib type and determine if it is NULL, or has
    206 the wrong type.
    207 *****************************************************************************/
    208 #define PS_WARN_PTR_NON_NULL(NAME) \
    209 if ((NAME) == NULL) { \
    210     psLogMsg(__func__, PS_LOG_WARN, "WARNING: %s is NULL.", #NAME); \
    211 } \
    212 
    213 #define PS_ASSERT_PTR_NON_NULL(NAME, RVAL) PS_ASSERT_GENERAL_PTR_NON_NULL(NAME, return RVAL)
    214 #define PS_ASSERT_GENERAL_PTR_NON_NULL(NAME, CLEANUP) \
    215 if ((NAME) == NULL) { \
    216     psError(PS_ERR_BAD_PARAMETER_NULL, true, \
    217             "Unallowable operation: %s is NULL.", \
    218             #NAME); \
    219     CLEANUP; \
    220 }
    221 
    222 #define PS_ASSERT_PTR_TYPE(NAME, TYPE, RVAL) \
    223 if ((NAME)->type.type != TYPE) { \
    224     psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    225             "Unallowable operation: %s has incorrect type.", \
    226             #NAME); \
    227     return(RVAL); \
    228 }
    229 
    230 #define PS_ASSERT_PTR_DIMEN(NAME, DIMEN, RVAL) PS_ASSERT_GENERAL_PTR_DIMEN(NAME, DIMEN, return RVAL)
    231 #define PS_ASSERT_GENERAL_PTR_DIMEN(NAME, DIMEN, CLEANUP) \
    232 if ((NAME)->type.dimen != DIMEN) { \
    233     psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    234             "Unallowable operation: %s has incorrect dimensionality.", \
    235             #NAME); \
    236     CLEANUP; \
    237 }
    238 
    239 #define PS_ASSERT_PTR_DIMEN_GENERAL_NOT(NAME, DIMEN, CLEANUP) \
    240 if ((NAME)->type.dimen == DIMEN) { \
    241     psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    242             "Unallowable operation: %s has incorrect dimensionality.", \
    243             #NAME); \
    244     CLEANUP; \
    245 }
    246 
    247 
    248 #define PS_ASSERT_PTRS_SIZE_EQUAL(PTR1, PTR2, RVAL) \
    249 if (PTR1->n != PTR2->n) { \
    250     psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
    251             "ptr %s has size %d, ptr %s has size %d.", \
    252             #PTR1, PTR1->n, #PTR2, PTR2->n); \
    253     return(RVAL); \
    254 }
    255 
    256 #define PS_ASSERT_PTR_TYPE_EQUAL(PTR1, PTR2, RVAL) PS_ASSERT_PTRS_TYPE_EQUAL_GENERAL(PTR1, PTR2, return RVAL)
    257 #define PS_ASSERT_PTRS_TYPE_EQUAL_GENERAL(PTR1, PTR2, CLEANUP) \
    258 if (PTR1->type.type != PTR2->type.type) { \
    259     psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    260             "ptr %s has type %d, ptr %s has type %d.", \
    261             #PTR1, PTR1->type.type, #PTR2, PTR2->type.type); \
    262     CLEANUP; \
    263 }
    264 
    265 
    266 /*****************************************************************************
    267     PS_VECTOR macros:
    268  *****************************************************************************/
    269 #define PS_ASSERT_VECTOR_NON_NULL(NAME, RVAL) PS_ASSERT_GENERAL_VECTOR_NON_NULL(NAME, return RVAL)
    270 #define PS_ASSERT_GENERAL_VECTOR_NON_NULL(NAME, CLEANUP) \
    271 if ((NAME) == NULL || (NAME)->data.U8 == NULL) { \
    272     psError(PS_ERR_BAD_PARAMETER_NULL, true, \
    273             "Unallowable operation: psVector %s or its data is NULL.", \
    274             #NAME); \
    275     CLEANUP; \
    276 } \
    277 
    278 #define PS_ASSERT_VECTOR_NON_EMPTY(NAME, RVAL) PS_ASSERT_GENERAL_VECTOR_NON_EMPTY(NAME, return RVAL)
    279 #define PS_ASSERT_GENERAL_VECTOR_NON_EMPTY(NAME, CLEANUP) \
    280 if ((NAME)->n < 1) { \
    281     psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
    282             "Unallowable operation: psVector %s has no elements.", \
    283             #NAME); \
    284     CLEANUP; \
    285 } \
    286 
    287 #define PS_ASSERT_VECTOR_TYPE_F32_OR_F64(NAME, RVAL) \
    288 if (((NAME)->type.type != PS_TYPE_F32) && ((NAME)->type.type != PS_TYPE_F64)) { \
    289     psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    290             "psVector %s: bad type(%d)", \
    291             #NAME, NAME->type.type); \
    292     return(RVAL); \
    293 } \
    294 
    295 #define PS_ASSERT_VECTOR_TYPE_S16_S32_F32(NAME, RVAL) \
    296 if (((NAME)->type.type != PS_TYPE_S16) && ((NAME)->type.type != PS_TYPE_S32) && ((NAME)->type.type != PS_TYPE_F32)) { \
    297     psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    298             "psVector %s: bad type(%d)", \
    299             #NAME, NAME->type.type); \
    300     return(RVAL); \
    301 } \
    302 
    303 #define PS_ASSERT_VECTOR_TYPE(NAME, TYPE, RVAL) \
    304 if ((NAME)->type.type != TYPE) { \
    305     psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    306             "Unallowable operation: psVector %s has incorrect type.", \
    307             #NAME); \
    308     return(RVAL); \
    309 }
    310 
    311 #define PS_ASSERT_VECTORS_SIZE_EQUAL(VEC1, VEC2, RVAL) \
    312 if (VEC1->n != VEC2->n) { \
    313     psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
    314             "psVector %s has size %d, psVector %s has size %d.", \
    315             #VEC1, VEC1->n, #VEC2, VEC2->n); \
    316     return(RVAL); \
    317 }
    318 
    319 #define PS_ASSERT_VECTOR_SIZE(VEC, SIZE, RVAL) \
    320 if (VEC->n != SIZE) { \
    321     psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
    322             "psVector %s has size %d, should be %d.", \
    323             #VEC, VEC->n, SIZE); \
    324     return(RVAL); \
    325 }
    326 
    327 #define PS_ASSERT_VECTOR_TYPE_EQUAL(VEC1, VEC2, RVAL) \
    328 if (VEC1->type.type != VEC2->type.type) { \
    329     psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
    330             "psVector %s has size %d, psVector %s has size %d.", \
    331             #VEC1, VEC1->type.type, #VEC2, VEC2->type.type); \
    332     return(RVAL); \
    333 }
    334 
    335 #define PS_VECTOR_PRINT_F32(NAME) \
    336 if (NAME != NULL) { \
    337     for (int my_i=0;my_i<(NAME)->n;my_i++) { \
    338         printf("%s->data.F32[%d] is %f\n", #NAME, my_i, (NAME)->data.F32[my_i]); \
    339     } \
    340     printf("\n"); \
    341 } else {\
    342     printf("MACRO WARNING: vector %s is NULL.\n", #NAME); \
    343 }\
    344 
    345 #define PS_VECTOR_PRINT_F64(NAME) \
    346 if (NAME != NULL) { \
    347     for (int my_i=0;my_i<(NAME)->n;my_i++) { \
    348         printf("%s->data.F64[%d] is %f\n", #NAME, my_i, (NAME)->data.F64[my_i]); \
    349     } \
    350     printf("\n"); \
    351 } else {\
    352     printf("MACRO WARNING: vector %s is NULL.\n", #NAME); \
    353 }\
    354 
    355 /*****************************************************************************
    356     PS_POLY macros:
    357 *****************************************************************************/
    358 #define PS_ASSERT_POLY1D(NAME, RVAL) \
    359 if (false == psMemCheckPolynomial1D(NAME)) { \
    360     psError(PS_ERR_BAD_PARAMETER_NULL, true, \
    361             "Unallowable operation: argument %s is not a psPolynomial1D struct.\n",\
    362             #NAME); \
    363     return(RVAL); \
    364 } \
    365 
    366 #define PS_ASSERT_POLY_NON_NULL(NAME, RVAL) \
    367 if ((NAME) == NULL || (NAME)->coeff == NULL) { \
    368     psError(PS_ERR_BAD_PARAMETER_NULL, true, \
    369             "Unallowable operation: polynomial %s or its coeffs is NULL.", \
    370             #NAME); \
    371     return(RVAL); \
    372 } \
    373 
    374 #define PS_ASSERT_POLY_TYPE(NAME, TYPE, RVAL) \
    375 if ((NAME)->type != TYPE) { \
    376     psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    377             "Unallowable operation: polynomial %s has wrong type.", #NAME); \
    378     return(RVAL); \
    379 } \
    380 
    381 #define PS_POLY_PRINT_1D(NAME) \
    382 printf("Poly %s: (nX) is (%d)\n", #NAME, NAME->nX);\
    383 for (psS32 i = 0 ; i < NAME->nX+1 ; i++) {\
    384     printf("%s->coeff[%d] is %f\n", #NAME, i, NAME->coeff[i]); \
    385 }\
    386 
    387 #define PS_POLY_PRINT_2D(NAME) \
    388 printf("Poly %s: (nX, nY) is (%d, %d)\n", #NAME, NAME->nX, NAME->nY);\
    389 for (psS32 i = 0 ; i < NAME->nX+1 ; i++) {\
    390     for (psS32 j = 0 ; j < NAME->nY+1 ; j++) {\
    391         printf("%s->coeff[%d][%d] is %f\n", #NAME, i, j, NAME->coeff[i][j]); \
    392     }\
    393 }\
    394 
    395 #define PS_PRINT_PLANE_TRANSFORM(NAME) \
    396 { \
    397     printf("---------------------- Plane Transform ----------------------\n"); \
    398     printf("x:\n"); \
    399     PS_POLY_PRINT_2D(NAME->x); \
    400     printf("y:\n"); \
    401     PS_POLY_PRINT_2D(NAME->y); \
    402 } \
    403 
    404 
    405 /*****************************************************************************
    406     PS_SPLINE macros:
    407 *****************************************************************************/
    408 #define PS_ASSERT_SPLINE(NAME, RVAL) \
    409 if (false == psMemCheckSpline1D(NAME)) { \
    410     psError(PS_ERR_BAD_PARAMETER_NULL, true, \
    411             "Unallowable operation: argument %s is not a psSpline1D struct.\n",\
    412             #NAME); \
    413     return(RVAL); \
    414 } \
    415 
    416 #define PS_ASSERT_SPLINE_NON_NULL(NAME, RVAL) \
    417 if ((NAME) == NULL) { \
    418     psError(PS_ERR_BAD_PARAMETER_NULL, true, \
    419             "Unallowable operation: psSpline1D %s is NULL.", \
    420             #NAME); \
    421     return(RVAL); \
    422 } \
    423 
    424 /*****************************************************************************
    425     PS_IMAGE macros:
    426 *****************************************************************************/
    427 #define PS_ASSERT_IMAGE_NON_NULL(NAME, RVAL) PS_ASSERT_GENERAL_IMAGE_NON_NULL(NAME, return RVAL)
    428 #define PS_ASSERT_GENERAL_IMAGE_NON_NULL(NAME, CLEANUP) \
    429 if ((NAME) == NULL || (NAME)->data.V == NULL) { \
    430     psError(PS_ERR_BAD_PARAMETER_NULL, true, \
    431             "Unallowable operation: psImage %s or its data is NULL.", \
    432             #NAME); \
    433     CLEANUP; \
    434 }
    435 
    436 #define PS_ASSERT_IMAGE_NON_EMPTY(NAME, RVAL) PS_ASSERT_GENERAL_IMAGE_NON_EMPTY(NAME, return RVAL)
    437 #define PS_ASSERT_GENERAL_IMAGE_NON_EMPTY(NAME, CLEANUP) \
    438 if ((NAME)->numCols < 1 || (NAME)->numRows < 1) { \
    439     psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
    440             "Unallowable operation: psImage %s has zero rows or columns (%dx%d).", \
    441             #NAME, (NAME)->numCols, (NAME)->numRows); \
    442     CLEANUP; \
    443 }
    444 
    445 #define PS_ASSERT_IMAGE_TYPE(NAME, TYPE, RVAL) \
    446 if ((NAME)->type.type != TYPE) { \
    447     psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    448             "Unallowable operation: psImage %s has incorrect type.", \
    449             #NAME); \
    450     return(RVAL); \
    451 }
    452 
    453 #define PS_ASSERT_IMAGES_SIZE_EQUAL(NAME1, NAME2, RVAL) \
    454 if (((NAME1)->numCols != (NAME2)->numCols) || \
    455         ((NAME1)->numRows != (NAME2)->numRows)) { \
    456     psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
    457             "Unallowable operation: psImages %s and %s are not the same size.", \
    458             #NAME1, #NAME2); \
    459     return(RVAL); \
    460 }
    461 
    462 #define PS_ASSERT_IMAGE_SIZE(NAME1, NUM_COLS, NUM_ROWS, RVAL) \
    463 if (((NAME1)->numCols != NUM_COLS) || \
    464         ((NAME1)->numRows != NUM_ROWS)) { \
    465     psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
    466             "Unallowable operation: psImages %s is not the correct size.", \
    467             #NAME1); \
    468     return(RVAL); \
    469 }
    470 
    471 #define PS_IMAGE_PRINT_F32(NAME) \
    472 printf("======== printing %s ========\n", #NAME); \
    473 for (int i = 0 ; i < (NAME)->numRows ; i++) { \
    474     for (int j = 0 ; j < (NAME)->numCols ; j++) { \
    475         printf("%.2f ", (NAME)->data.F32[i][j]); \
    476     } \
    477     printf("\n"); \
    478 }\
    479 
    480 #define PS_IMAGE_PRINT_F64(NAME) \
    481 printf("======== printing %s ========\n", #NAME); \
    482 for (int i = 0 ; i < (NAME)->numRows ; i++) { \
    483     for (int j = 0 ; j < (NAME)->numCols ; j++) { \
    484         printf("%.2f ", (NAME)->data.F64[i][j]); \
    485     } \
    486     printf("\n"); \
    487 }\
    488 
    489 /*****************************************************************************
    49047    Misc. macros:
    49148*****************************************************************************/
     
    49956((A) * (A))
    50057
    501 # define PS_SWAP(X,Y) {double tmp=(X); (X) = (Y); (Y) = tmp;}
     58#define PS_SWAP(X,Y) {double tmp=(X); (X) = (Y); (Y) = tmp;}
Note: See TracChangeset for help on using the changeset viewer.