os/ossrv/stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/valcmp.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
sl@0
     2
sl@0
     3
/************************************************************************
sl@0
     4
 *
sl@0
     5
 * valcmp.cpp - definitions of the rw_valcmp() family of helper functions
sl@0
     6
 *
sl@0
     7
 * $Id: valcmp.cpp 332687 2005-11-12 00:47:57Z sebor $
sl@0
     8
 *
sl@0
     9
 ************************************************************************
sl@0
    10
 *
sl@0
    11
 * Copyright (c) 1994-2005 Quovadx,  Inc., acting through its  Rogue Wave
sl@0
    12
 * Software division. Licensed under the Apache License, Version 2.0 (the
sl@0
    13
 * "License");  you may  not use this file except  in compliance with the
sl@0
    14
 * License.    You    may   obtain   a   copy   of    the   License    at
sl@0
    15
 * http://www.apache.org/licenses/LICENSE-2.0.    Unless   required    by
sl@0
    16
 * applicable law  or agreed to  in writing,  software  distributed under
sl@0
    17
 * the License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR
sl@0
    18
 * CONDITIONS OF  ANY KIND, either  express or implied.  See  the License
sl@0
    19
 * for the specific language governing permissions  and limitations under
sl@0
    20
 * the License.
sl@0
    21
 * 
sl@0
    22
 **************************************************************************/
sl@0
    23
sl@0
    24
// expand _TEST_EXPORT macros
sl@0
    25
#define _RWSTD_TEST_SRC
sl@0
    26
sl@0
    27
#include <cfloat>
sl@0
    28
#include <valcmp.h>
sl@0
    29
sl@0
    30
#include <stdio.h>    // for fprintf, stderr
sl@0
    31
#include <stdlib.h>   // for abort
sl@0
    32
#include <string.h>   // for memcmp
sl@0
    33
sl@0
    34
/**************************************************************************/
sl@0
    35
sl@0
    36
typedef unsigned char UChar;
sl@0
    37
sl@0
    38
sl@0
    39
static const UChar
sl@0
    40
_rw_upper [] = {
sl@0
    41
sl@0
    42
#if 'A' == 0x41
sl@0
    43
sl@0
    44
    // basic ASCII:
sl@0
    45
    //          .0  .1  .2  .3  .4  .5  .6  .7  .8  .9  .a  .b  .c  .d  .e  .f
sl@0
    46
    //         --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
sl@0
    47
    //         NUL SOH STX ETX EOT ENQ ACK BEL BS  TAB  LF  VT  FF  CR  SO  SI
sl@0
    48
    /* 0. */ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
sl@0
    49
    //         DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN  EM SUB ESC  FS  GS  RS  US
sl@0
    50
    /* 1. */ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
sl@0
    51
    //         SPC   !   "   #   $   %   '   '   (   )   *   +   ,   -   .   /
sl@0
    52
    /* 2. */ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
sl@0
    53
    //           0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?
sl@0
    54
    /* 3. */ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
sl@0
    55
    //               A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
sl@0
    56
    /* 4. */ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
sl@0
    57
    //           P   Q   R   S   T   U   V   W   X   Y   Z   [   \   ]   ^   _
sl@0
    58
    /* 5. */ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
sl@0
    59
    //           `   a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
sl@0
    60
    /* 6. */ "\x60\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
sl@0
    61
    //           p   q   r   s   t   u   v   w   x   y   z   {   |   }   ~ DEL
sl@0
    62
    /* 7. */ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x7b\x7c\x7d\x7e\x7f"
sl@0
    63
sl@0
    64
    // extended ASCII:
sl@0
    65
    /* 8. */ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
sl@0
    66
    /* 9. */ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
sl@0
    67
    /* a. */ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
sl@0
    68
    /* b. */ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
sl@0
    69
    /* c. */ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
sl@0
    70
    /* d. */ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
sl@0
    71
    /* e. */ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
sl@0
    72
    /* f. */ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
sl@0
    73
sl@0
    74
#elif 'A' == 0xc1
sl@0
    75
sl@0
    76
    // EBCDIC:
sl@0
    77
    //          .0  .1  .2  .3  .4  .5  .6  .7  .8  .9  .a  .b  .c  .d  .e  .f
sl@0
    78
    //         --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
sl@0
    79
    //         NUL SOH STX ETX  PF  HT  LC DEL         SMM  VT  FF  CR  SO  SI
sl@0
    80
    /* 0. */ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
sl@0
    81
    //         DLE DC1 DC2  TM RES  NL  BS  IL CAN  EM  CC CU1 IFS IGS IRS IUS
sl@0
    82
    /* 1. */ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
sl@0
    83
    //          DS SOS  FS     BYP  LF ETB ESC          SM CU2     ENQ ACK BEL
sl@0
    84
    /* 2. */ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
sl@0
    85
    //                 SYN      PN  RS  UC EOT             CU3 DC4 NAK     SUB
sl@0
    86
    /* 3. */ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
sl@0
    87
    //          SP                                     ct.  .   <   (   +   |
sl@0
    88
    /* 4. */ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
sl@0
    89
    //          &                                       !   $   *   )   ;   ~
sl@0
    90
    /* 5. */ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
sl@0
    91
    //          -   /                                       ,   %   _   >   ?
sl@0
    92
    /* 6. */ "\x60\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
sl@0
    93
    //                                                  :   #   @   '   =   "
sl@0
    94
    /* 7. */ "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
sl@0
    95
    //              a   b   c   d   e   f   g   h   i
sl@0
    96
    /* 8. */ "\x80\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\x8a\x8b\x8c\x8d\x8e\x8f"
sl@0
    97
    //              j   k   l   m   n   o   p   q   r
sl@0
    98
    /* 9. */ "\x90\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\x9a\x9b\x9c\x9d\x9e\x9f"
sl@0
    99
    //                  s   t   u   v   w   x   y   z
sl@0
   100
    /* a. */ "\xa0\xa1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xaa\xab\xac\xad\xae\xaf"
sl@0
   101
    //                                            `
sl@0
   102
    /* b. */ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
sl@0
   103
    //              A   B   C   D   E   F   G   H   I
sl@0
   104
    /* c. */ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
sl@0
   105
    //              J   K   L   M   N   O   P   Q   R
sl@0
   106
    /* d. */ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
sl@0
   107
    //                  S   T   U   V   W   X   Y   Z
sl@0
   108
    /* e. */ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
sl@0
   109
    //          0   1   2   3   4   5   6   7   8   9
sl@0
   110
    /* f. */ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
sl@0
   111
sl@0
   112
#else   // 'A' != 0x41 && 'A' != 0xc1
sl@0
   113
#  error unknown character set (neither ASCII nor EBCDIC)
sl@0
   114
#endif   // ASCII or EBCDIC
sl@0
   115
sl@0
   116
};
sl@0
   117
sl@0
   118
sl@0
   119
// returns 1 iff all size bytes of the object pointed to by buf are 0
sl@0
   120
static int
sl@0
   121
_rw_iszero (const void *buf, _RWSTD_SIZE_T size)
sl@0
   122
{
sl@0
   123
    for (_RWSTD_SIZE_T i = 0; i != size; ++i)
sl@0
   124
        if (_RWSTD_STATIC_CAST (const UChar*, buf)[i])
sl@0
   125
            return 0;
sl@0
   126
sl@0
   127
    return 1;
sl@0
   128
}
sl@0
   129
sl@0
   130
sl@0
   131
// compares two objects of equal size
sl@0
   132
static int
sl@0
   133
_rw_cmpx (const void *buf1,
sl@0
   134
          const void *buf2,
sl@0
   135
          _RWSTD_SIZE_T nelems,
sl@0
   136
          _RWSTD_SIZE_T size,
sl@0
   137
          int           flags = 0)
sl@0
   138
{
sl@0
   139
    const UChar *p1 = _RWSTD_STATIC_CAST (const UChar*, buf1);
sl@0
   140
    const UChar *p2 = _RWSTD_STATIC_CAST (const UChar*, buf2);
sl@0
   141
sl@0
   142
    int ret = 0;
sl@0
   143
sl@0
   144
    for ( ; nelems; p1 += size, p2 += size, --nelems) {
sl@0
   145
sl@0
   146
        ret = memcmp (p1, p2, size);
sl@0
   147
sl@0
   148
        if (flags & CMP_NULTERM) {
sl@0
   149
sl@0
   150
            const int zero1 = _rw_iszero (p1, size);
sl@0
   151
            const int zero2 = _rw_iszero (p2, size);
sl@0
   152
sl@0
   153
            if (zero1 || zero2) {
sl@0
   154
                ret = zero1 - zero2;
sl@0
   155
                break;
sl@0
   156
            }
sl@0
   157
        }
sl@0
   158
sl@0
   159
        if (ret && (flags & CMP_NOCASE)) {
sl@0
   160
            // FIXME: implement
sl@0
   161
            fprintf (stderr,
sl@0
   162
                     "%s:%d: case insensitive comparison not implemented\n",
sl@0
   163
                     __FILE__, __LINE__);
sl@0
   164
            abort ();
sl@0
   165
        }
sl@0
   166
    }
sl@0
   167
sl@0
   168
    if (flags & CMP_RETOFF) {
sl@0
   169
        // FIXME: implement
sl@0
   170
        fprintf (stderr,
sl@0
   171
                 "%s:%d: returning offset not implemented\n",
sl@0
   172
                 __FILE__, __LINE__);
sl@0
   173
        abort ();
sl@0
   174
    }
sl@0
   175
sl@0
   176
    return ret < 0 ? -1 : ret ? +1 : 0;
sl@0
   177
}
sl@0
   178
sl@0
   179
sl@0
   180
// compares two byte arrays
sl@0
   181
static int
sl@0
   182
_rw_cmp1 (const void *buf1,
sl@0
   183
          const void *buf2,
sl@0
   184
          _RWSTD_SIZE_T nelems,
sl@0
   185
          int           flags = 0)
sl@0
   186
{
sl@0
   187
#ifdef _RWSTD_UINT8_T
sl@0
   188
sl@0
   189
    typedef _RWSTD_UINT8_T UI8T;
sl@0
   190
sl@0
   191
    if (0 == flags) {
sl@0
   192
        const int ret = memcmp (buf1, buf2, nelems);
sl@0
   193
        return ret < 0 ? -1 : ret ? +1 : 0;
sl@0
   194
    }
sl@0
   195
sl@0
   196
    if (CMP_NULTERM == flags) {
sl@0
   197
        const int ret =
sl@0
   198
            strncmp (_RWSTD_STATIC_CAST (const char*, buf1),
sl@0
   199
                     _RWSTD_STATIC_CAST (const char*, buf2),
sl@0
   200
                     nelems);
sl@0
   201
        return ret < 0 ? -1 : ret ? +1 : 0;
sl@0
   202
    }
sl@0
   203
sl@0
   204
    int ret = 0;
sl@0
   205
    int inx = 0;
sl@0
   206
sl@0
   207
    const UI8T *pi1 = _RWSTD_STATIC_CAST (const UI8T*, buf1);
sl@0
   208
    const UI8T *pi2 = _RWSTD_STATIC_CAST (const UI8T*, buf2);
sl@0
   209
sl@0
   210
    for (; nelems; ++pi1, ++pi2, --nelems, ++inx) {
sl@0
   211
sl@0
   212
        const UI8T ui1 = *pi1;
sl@0
   213
        const UI8T ui2 = *pi2;
sl@0
   214
sl@0
   215
        if (flags & CMP_NULTERM) {
sl@0
   216
sl@0
   217
            if (0 == ui1) {
sl@0
   218
                ret = ui2 ? -1 : 0;
sl@0
   219
                break;
sl@0
   220
            }
sl@0
   221
sl@0
   222
            if (0 == ui2) {
sl@0
   223
                ret = +1;
sl@0
   224
                break;
sl@0
   225
            }
sl@0
   226
        }
sl@0
   227
sl@0
   228
        if (ui1 != ui2) {
sl@0
   229
            if (flags & CMP_NOCASE) {
sl@0
   230
                if (_rw_upper [ui1] != _rw_upper [ui2]) {
sl@0
   231
                    ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1;
sl@0
   232
                    break;
sl@0
   233
                }
sl@0
   234
            }
sl@0
   235
            else {
sl@0
   236
                ret = ui1 < ui2 ? -1 : +1;
sl@0
   237
                break;
sl@0
   238
            }
sl@0
   239
        }
sl@0
   240
    }
sl@0
   241
sl@0
   242
    if (CMP_RETOFF & flags) {
sl@0
   243
        ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1;
sl@0
   244
    }
sl@0
   245
            
sl@0
   246
    return ret;
sl@0
   247
sl@0
   248
#else // if !defined (_RWSTD_UINT8_T)
sl@0
   249
#  error _RWSTD_UINT8_T not #defined (configuration problem?)
sl@0
   250
#endif   // _RWSTD_UINT8_T
sl@0
   251
sl@0
   252
}
sl@0
   253
sl@0
   254
sl@0
   255
// compares two arrays of objects each 16 bits in size
sl@0
   256
static int
sl@0
   257
_rw_cmp2 (const void *buf1,
sl@0
   258
          const void *buf2,
sl@0
   259
          _RWSTD_SIZE_T nelems,
sl@0
   260
          int           flags = 0)
sl@0
   261
{
sl@0
   262
#ifdef _RWSTD_UINT16_T
sl@0
   263
sl@0
   264
    typedef _RWSTD_UINT16_T UI16T;
sl@0
   265
sl@0
   266
    int ret = 0;
sl@0
   267
    int inx = 0;
sl@0
   268
sl@0
   269
    const UI16T *pi1 = _RWSTD_STATIC_CAST (const UI16T*, buf1);
sl@0
   270
    const UI16T *pi2 = _RWSTD_STATIC_CAST (const UI16T*, buf2);
sl@0
   271
sl@0
   272
    for (; nelems; ++pi1, ++pi2, --nelems) {
sl@0
   273
sl@0
   274
        const UI16T ui1 = *pi1;
sl@0
   275
        const UI16T ui2 = *pi2;
sl@0
   276
sl@0
   277
        if (flags & CMP_NULTERM) {
sl@0
   278
sl@0
   279
            if (0 == ui1) {
sl@0
   280
                ret = ui2 ? -1 : 0;
sl@0
   281
                break;
sl@0
   282
            }
sl@0
   283
sl@0
   284
            if (0 == ui2) {
sl@0
   285
                ret = +1;
sl@0
   286
                break;
sl@0
   287
            }
sl@0
   288
        }
sl@0
   289
sl@0
   290
        if (ui1 != ui2) {
sl@0
   291
            if (flags & CMP_NOCASE) {
sl@0
   292
                if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) {
sl@0
   293
                    ret = ui1 < ui2 ? -1 : +1;
sl@0
   294
                    break;
sl@0
   295
                }
sl@0
   296
                else if (_rw_upper [ui1] != _rw_upper [ui2]) {
sl@0
   297
                    ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1;
sl@0
   298
                    break;
sl@0
   299
                }
sl@0
   300
            }
sl@0
   301
            else {
sl@0
   302
                ret = ui1 < ui2 ? -1 : +1;
sl@0
   303
                break;
sl@0
   304
            }
sl@0
   305
        }
sl@0
   306
    }
sl@0
   307
sl@0
   308
    if (CMP_RETOFF & flags) {
sl@0
   309
        ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1;
sl@0
   310
    }
sl@0
   311
            
sl@0
   312
    return ret;
sl@0
   313
sl@0
   314
#else   // if !defined (_RWSTD_UINT16_T)
sl@0
   315
sl@0
   316
    return _rw_cmpx (buf1, buf2, nelems, 2, flags);
sl@0
   317
sl@0
   318
#endif   // _RWSTD_UINT16_T
sl@0
   319
}
sl@0
   320
sl@0
   321
sl@0
   322
// compares two arrays of objects each 32 bits in size
sl@0
   323
static int
sl@0
   324
_rw_cmp4 (const void *buf1,
sl@0
   325
          const void *buf2,
sl@0
   326
          _RWSTD_SIZE_T nelems,
sl@0
   327
          int           flags = 0)
sl@0
   328
{
sl@0
   329
#ifdef _RWSTD_UINT32_T
sl@0
   330
sl@0
   331
    typedef _RWSTD_UINT32_T UI32T;
sl@0
   332
sl@0
   333
    int ret = 0;
sl@0
   334
    int inx = 0;
sl@0
   335
sl@0
   336
    const UI32T *pi1 = _RWSTD_STATIC_CAST (const UI32T*, buf1);
sl@0
   337
    const UI32T *pi2 = _RWSTD_STATIC_CAST (const UI32T*, buf2);
sl@0
   338
sl@0
   339
    for (; nelems; ++pi1, ++pi2, --nelems) {
sl@0
   340
sl@0
   341
        const UI32T ui1 = *pi1;
sl@0
   342
        const UI32T ui2 = *pi2;
sl@0
   343
sl@0
   344
        if (flags & CMP_NULTERM) {
sl@0
   345
sl@0
   346
            if (0 == ui1) {
sl@0
   347
                ret = ui2 ? -1 : 0;
sl@0
   348
                break;
sl@0
   349
            }
sl@0
   350
sl@0
   351
            if (0 == ui2) {
sl@0
   352
                ret = +1;
sl@0
   353
                break;
sl@0
   354
            }
sl@0
   355
        }
sl@0
   356
sl@0
   357
        if (ui1 != ui2) {
sl@0
   358
            if (flags & CMP_NOCASE) {
sl@0
   359
                if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) {
sl@0
   360
                    ret = ui1 < ui2 ? -1 : +1;
sl@0
   361
                    break;
sl@0
   362
                }
sl@0
   363
                else if (_rw_upper [ui1] != _rw_upper [ui2]) {
sl@0
   364
                    ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1;
sl@0
   365
                    break;
sl@0
   366
                }
sl@0
   367
            }
sl@0
   368
            else {
sl@0
   369
                ret = ui1 < ui2 ? -1 : +1;
sl@0
   370
                break;
sl@0
   371
            }
sl@0
   372
        }
sl@0
   373
    }
sl@0
   374
sl@0
   375
    if (CMP_RETOFF & flags) {
sl@0
   376
        ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1;
sl@0
   377
    }
sl@0
   378
            
sl@0
   379
    return ret;
sl@0
   380
sl@0
   381
#else   // if !defined (_RWSTD_UINT32_T)
sl@0
   382
sl@0
   383
    return _rw_cmpx (buf1, buf2, nelems, 4, flags);
sl@0
   384
sl@0
   385
#endif   // _RWSTD_UINT32_T
sl@0
   386
}
sl@0
   387
sl@0
   388
sl@0
   389
// compares two arrays of objects each 64 bits in size
sl@0
   390
static int
sl@0
   391
_rw_cmp8 (const void *buf1,
sl@0
   392
          const void *buf2,
sl@0
   393
          _RWSTD_SIZE_T nelems,
sl@0
   394
          int           flags = 0)
sl@0
   395
{
sl@0
   396
#ifdef _RWSTD_UINT64_T
sl@0
   397
sl@0
   398
    typedef _RWSTD_UINT64_T UI64T;
sl@0
   399
sl@0
   400
    int ret = 0;
sl@0
   401
    int inx = 0;
sl@0
   402
sl@0
   403
    const UI64T *pi1 = _RWSTD_STATIC_CAST (const UI64T*, buf1);
sl@0
   404
    const UI64T *pi2 = _RWSTD_STATIC_CAST (const UI64T*, buf2);
sl@0
   405
sl@0
   406
    for (; nelems; ++pi1, ++pi2, --nelems) {
sl@0
   407
sl@0
   408
        const UI64T ui1 = *pi1;
sl@0
   409
        const UI64T ui2 = *pi2;
sl@0
   410
sl@0
   411
        if (flags & CMP_NULTERM) {
sl@0
   412
sl@0
   413
            if (0 == ui1) {
sl@0
   414
                ret = ui2 ? -1 : 0;
sl@0
   415
                break;
sl@0
   416
            }
sl@0
   417
sl@0
   418
            if (0 == ui2) {
sl@0
   419
                ret = +1;
sl@0
   420
                break;
sl@0
   421
            }
sl@0
   422
        }
sl@0
   423
sl@0
   424
        if (ui1 != ui2) {
sl@0
   425
            if (flags & CMP_NOCASE) {
sl@0
   426
                if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) {
sl@0
   427
                    ret = ui1 < ui2 ? -1 : +1;
sl@0
   428
                    break;
sl@0
   429
                }
sl@0
   430
                else if (_rw_upper [ui1] != _rw_upper [ui2]) {
sl@0
   431
                    ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1;
sl@0
   432
                    break;
sl@0
   433
                }
sl@0
   434
            }
sl@0
   435
            else {
sl@0
   436
                ret = ui1 < ui2 ? -1 : +1;
sl@0
   437
                break;
sl@0
   438
            }
sl@0
   439
        }
sl@0
   440
    }
sl@0
   441
sl@0
   442
    if (CMP_RETOFF & flags) {
sl@0
   443
        ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1;
sl@0
   444
    }
sl@0
   445
            
sl@0
   446
    return ret;
sl@0
   447
sl@0
   448
#else   // if !defined (_RWSTD_UINT64_T)
sl@0
   449
sl@0
   450
    return _rw_cmpx (buf1, buf2, nelems, 8, flags);
sl@0
   451
sl@0
   452
#endif   // _RWSTD_UINT64_T
sl@0
   453
}
sl@0
   454
sl@0
   455
sl@0
   456
// compares two arrays of objects of unequal size
sl@0
   457
static int
sl@0
   458
_rw_cmpxx (const void*   buf1,
sl@0
   459
           const void*   buf2,
sl@0
   460
           _RWSTD_SIZE_T nelems,
sl@0
   461
           _RWSTD_SIZE_T size1,
sl@0
   462
           _RWSTD_SIZE_T size2,
sl@0
   463
           int           flags)
sl@0
   464
{
sl@0
   465
    int ret = 0;
sl@0
   466
    int inx = 0;
sl@0
   467
sl@0
   468
    for (; nelems; --nelems, ++inx) {
sl@0
   469
sl@0
   470
#ifdef _RWSTD_UINT64_T
sl@0
   471
sl@0
   472
        _RWSTD_UINT64_T ui1;
sl@0
   473
        _RWSTD_UINT64_T ui2;
sl@0
   474
sl@0
   475
#else   // if !defined (_RWSTD_UINT64_T)
sl@0
   476
sl@0
   477
        _RWSTD_SIZE_T ui1;
sl@0
   478
        _RWSTD_SIZE_T ui2;
sl@0
   479
sl@0
   480
#endif   // _RWSTD_UINT64_T
sl@0
   481
sl@0
   482
        switch (size1) {
sl@0
   483
sl@0
   484
#ifdef _RWSTD_UINT8_T
sl@0
   485
sl@0
   486
        case 1: {
sl@0
   487
            const _RWSTD_UINT8_T* ptr =
sl@0
   488
                _RWSTD_STATIC_CAST (const _RWSTD_UINT8_T*, buf1);
sl@0
   489
            ui1 = *ptr++;
sl@0
   490
            buf1 = ptr;
sl@0
   491
            break;
sl@0
   492
        }
sl@0
   493
sl@0
   494
#endif   // _RWSTD_UINT8_T
sl@0
   495
sl@0
   496
#ifdef _RWSTD_UINT16_T
sl@0
   497
sl@0
   498
        case 2: {
sl@0
   499
            const _RWSTD_UINT16_T* ptr =
sl@0
   500
                _RWSTD_STATIC_CAST (const _RWSTD_UINT16_T*, buf1);
sl@0
   501
            ui1 = *ptr++;
sl@0
   502
            buf1 = ptr;
sl@0
   503
            break;
sl@0
   504
        }
sl@0
   505
sl@0
   506
#endif   // _RWSTD_UINT16_T
sl@0
   507
sl@0
   508
#ifdef _RWSTD_UINT32_T
sl@0
   509
sl@0
   510
        case 4: {
sl@0
   511
            const _RWSTD_UINT32_T* ptr =
sl@0
   512
                _RWSTD_STATIC_CAST (const _RWSTD_UINT32_T*, buf1);
sl@0
   513
            ui1 = *ptr++;
sl@0
   514
            buf1 = ptr;
sl@0
   515
            break;
sl@0
   516
        }
sl@0
   517
sl@0
   518
#endif   // _RWSTD_UINT32_T
sl@0
   519
sl@0
   520
#ifdef _RWSTD_UINT64_T
sl@0
   521
sl@0
   522
        case 8: {
sl@0
   523
            const _RWSTD_UINT64_T* ptr =
sl@0
   524
                _RWSTD_STATIC_CAST (const _RWSTD_UINT64_T*, buf1);
sl@0
   525
            ui1 = *ptr++;
sl@0
   526
            buf1 = ptr;
sl@0
   527
            break;
sl@0
   528
        }
sl@0
   529
sl@0
   530
#endif   // _RWSTD_UINT64_T
sl@0
   531
sl@0
   532
        default:
sl@0
   533
            fprintf (stderr,
sl@0
   534
                     "%s:%d: comparison of objects %u and %u bytes in size "
sl@0
   535
                     "not implemented\n", __FILE__, __LINE__,
sl@0
   536
                     unsigned (size1), unsigned (size2));
sl@0
   537
            abort ();
sl@0
   538
        }
sl@0
   539
sl@0
   540
        switch (size2) {
sl@0
   541
sl@0
   542
#ifdef _RWSTD_UINT8_T
sl@0
   543
sl@0
   544
        case 1: {
sl@0
   545
            const _RWSTD_UINT8_T* ptr =
sl@0
   546
                _RWSTD_STATIC_CAST (const _RWSTD_UINT8_T*, buf2);
sl@0
   547
            ui2 = *ptr++;
sl@0
   548
            buf2 = ptr;
sl@0
   549
            break;
sl@0
   550
        }
sl@0
   551
sl@0
   552
#endif   // _RWSTD_UINT8_T
sl@0
   553
sl@0
   554
#ifdef _RWSTD_UINT16_T
sl@0
   555
sl@0
   556
        case 2: {
sl@0
   557
            const _RWSTD_UINT16_T* ptr =
sl@0
   558
                _RWSTD_STATIC_CAST (const _RWSTD_UINT16_T*, buf2);
sl@0
   559
            ui2 = *ptr++;
sl@0
   560
            buf2 = ptr;
sl@0
   561
            break;
sl@0
   562
        }
sl@0
   563
sl@0
   564
#endif   // _RWSTD_UINT16_T
sl@0
   565
sl@0
   566
#ifdef _RWSTD_UINT32_T
sl@0
   567
sl@0
   568
        case 4: {
sl@0
   569
            const _RWSTD_UINT32_T* ptr =
sl@0
   570
                _RWSTD_STATIC_CAST (const _RWSTD_UINT32_T*, buf2);
sl@0
   571
            ui2 = *ptr++;
sl@0
   572
            buf2 = ptr;
sl@0
   573
            break;
sl@0
   574
        }
sl@0
   575
sl@0
   576
#endif   // _RWSTD_UINT32_T
sl@0
   577
sl@0
   578
#ifdef _RWSTD_UINT64_T
sl@0
   579
sl@0
   580
        case 8: {
sl@0
   581
            const _RWSTD_UINT64_T* ptr =
sl@0
   582
                _RWSTD_STATIC_CAST (const _RWSTD_UINT64_T*, buf2);
sl@0
   583
            ui2 = *ptr++;
sl@0
   584
            buf2 = ptr;
sl@0
   585
            break;
sl@0
   586
        }
sl@0
   587
sl@0
   588
#endif   // _RWSTD_UINT64_T
sl@0
   589
sl@0
   590
        default:
sl@0
   591
            fprintf (stderr,
sl@0
   592
                     "%s:%d: comparison of objects %u and %u bytes in size "
sl@0
   593
                     "not implemented\n", __FILE__, __LINE__,
sl@0
   594
                     unsigned (size1), unsigned (size2));
sl@0
   595
            abort ();
sl@0
   596
        }
sl@0
   597
sl@0
   598
        if (flags & CMP_NULTERM) {
sl@0
   599
sl@0
   600
            if (0 == ui1) {
sl@0
   601
                ret = ui2 ? -1 : 0;
sl@0
   602
                break;
sl@0
   603
            }
sl@0
   604
sl@0
   605
            if (0 == ui2) {
sl@0
   606
                ret = +1;
sl@0
   607
                break;
sl@0
   608
            }
sl@0
   609
        }
sl@0
   610
sl@0
   611
        if (ui1 != ui2) {
sl@0
   612
            if (flags & CMP_NOCASE) {
sl@0
   613
                if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) {
sl@0
   614
                    ret = ui1 < ui2 ? -1 : +1;
sl@0
   615
                    break;
sl@0
   616
                }
sl@0
   617
                else if (_rw_upper [ui1] != _rw_upper [ui2]) {
sl@0
   618
                    ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1;
sl@0
   619
                    break;
sl@0
   620
                }
sl@0
   621
            }
sl@0
   622
            else {
sl@0
   623
                ret = ui1 < ui2 ? -1 : +1;
sl@0
   624
                break;
sl@0
   625
            }
sl@0
   626
        }
sl@0
   627
    }
sl@0
   628
sl@0
   629
    if (CMP_RETOFF & flags) {
sl@0
   630
        ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1;
sl@0
   631
    }
sl@0
   632
sl@0
   633
    return ret;
sl@0
   634
}
sl@0
   635
sl@0
   636
sl@0
   637
_TEST_EXPORT int
sl@0
   638
rw_valcmp (const void*   buf1,
sl@0
   639
           const void*   buf2,
sl@0
   640
           _RWSTD_SIZE_T nelems,
sl@0
   641
           _RWSTD_SIZE_T size1,
sl@0
   642
           _RWSTD_SIZE_T size2,
sl@0
   643
           int           flags /* = 0 */)
sl@0
   644
{
sl@0
   645
    if (size1 == size2) {
sl@0
   646
sl@0
   647
        switch (size1) {
sl@0
   648
        case 1: return _rw_cmp1 (buf1, buf2, nelems, flags);
sl@0
   649
        case 2: return _rw_cmp2 (buf1, buf2, nelems, flags);
sl@0
   650
        case 4: return _rw_cmp4 (buf1, buf2, nelems, flags);
sl@0
   651
        case 8: return _rw_cmp8 (buf1, buf2, nelems, flags);
sl@0
   652
        }
sl@0
   653
sl@0
   654
        return _rw_cmpx (buf1, buf2, nelems, size1, flags);
sl@0
   655
    }
sl@0
   656
sl@0
   657
    return _rw_cmpxx (buf1, buf2, nelems, size1, size2, flags);
sl@0
   658
}
sl@0
   659
sl@0
   660
sl@0
   661
_TEST_EXPORT int
sl@0
   662
rw_strncmp (const char*   str1,
sl@0
   663
            const char*   str2,
sl@0
   664
            _RWSTD_SIZE_T nelems /* = _RWSTD_SIZE_MAX */,
sl@0
   665
           int            flags /* = CMP_NULTERM */)
sl@0
   666
{
sl@0
   667
    return rw_valcmp (str1, str2, nelems, 1, 1, flags);
sl@0
   668
}
sl@0
   669
sl@0
   670
sl@0
   671
#ifndef _RWSTD_NO_WCHAR_T
sl@0
   672
sl@0
   673
_TEST_EXPORT int
sl@0
   674
rw_strncmp (const char*    str1,
sl@0
   675
            const wchar_t* str2,
sl@0
   676
            _RWSTD_SIZE_T  nelems /* = _RWSTD_SIZE_MAX */,
sl@0
   677
           int             flags /* = CMP_NULTERM */)
sl@0
   678
{
sl@0
   679
    return rw_valcmp (str1, str2, nelems, 1, sizeof (wchar_t), flags);
sl@0
   680
}
sl@0
   681
sl@0
   682
sl@0
   683
_TEST_EXPORT int
sl@0
   684
rw_strncmp (const wchar_t* str1,
sl@0
   685
            const char*    str2,
sl@0
   686
            _RWSTD_SIZE_T  nelems /* = _RWSTD_SIZE_MAX */,
sl@0
   687
            int             flags /* = CMP_NULTERM */)
sl@0
   688
{
sl@0
   689
    return rw_valcmp (str1, str2, nelems, sizeof (wchar_t), 1, flags);
sl@0
   690
}
sl@0
   691
sl@0
   692
sl@0
   693
_TEST_EXPORT int
sl@0
   694
rw_strncmp (const wchar_t* str1,
sl@0
   695
            const wchar_t* str2,
sl@0
   696
            _RWSTD_SIZE_T  nelems /* = _RWSTD_SIZE_MAX */,
sl@0
   697
           int             flags /* = CMP_NULTERM */)
sl@0
   698
{
sl@0
   699
    return rw_valcmp (str1, str2, nelems,
sl@0
   700
                      sizeof (wchar_t), sizeof (wchar_t), flags);
sl@0
   701
}
sl@0
   702
sl@0
   703
#endif   // _RWSTD_NO_WCHAR_T
sl@0
   704
sl@0
   705
sl@0
   706
// floating point comparison helpers based on
sl@0
   707
// http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
sl@0
   708
sl@0
   709
_TEST_EXPORT int
sl@0
   710
rw_fltcmp (float x, float y)
sl@0
   711
{
sl@0
   712
#if _RWSTD_SHRT_SIZE == _RWSTD_INT_SIZE
sl@0
   713
    typedef short IntT;
sl@0
   714
    #ifdef __ARMCC__
sl@0
   715
    #pragma diag_suppress 68
sl@0
   716
    #endif
sl@0
   717
    const IntT imin = _RWSTD_SHRT_MIN;
sl@0
   718
    
sl@0
   719
#elif _RWSTD_FLT_SIZE == _RWSTD_INT_SIZE
sl@0
   720
    typedef int IntT;
sl@0
   721
    const IntT imin = _RWSTD_INT_MIN;
sl@0
   722
#elif _RWSTD_FLT_SIZE == _RWSTD_LONG_SIZE
sl@0
   723
    typedef long IntT;
sl@0
   724
    const IntT imin = _RWSTD_LONG_MIN;
sl@0
   725
#elif _RWSTD_FLT_SIZE == _RWSTD_LLONG_SIZE
sl@0
   726
    typedef _RWSTD_LONG_LONG IntT;
sl@0
   727
    const IntT imin = _RWSTD_LLONG_MIN;
sl@0
   728
#else
sl@0
   729
    // ???
sl@0
   730
#  error no integral type of the same size as float exists
sl@0
   731
#endif
sl@0
   732
sl@0
   733
    if (x == y)
sl@0
   734
        return 0;
sl@0
   735
sl@0
   736
    // make both arguments lexicographically ordered as twos-complement ints
sl@0
   737
    IntT x_int = *(IntT*)&x;
sl@0
   738
    if (x_int < 0)
sl@0
   739
        x_int = imin - x_int;
sl@0
   740
sl@0
   741
    IntT y_int = *(IntT*)&y;
sl@0
   742
    if (y_int < 0)
sl@0
   743
        y_int = imin - y_int;
sl@0
   744
sl@0
   745
    const IntT int_diff = x_int - y_int;
sl@0
   746
sl@0
   747
    return int_diff;
sl@0
   748
}
sl@0
   749
sl@0
   750
sl@0
   751
#define Abs(x) ((x) < 0 ? -(x) : (x))
sl@0
   752
sl@0
   753
sl@0
   754
_TEST_EXPORT int
sl@0
   755
rw_dblcmp (double x, double y)
sl@0
   756
{
sl@0
   757
#if _RWSTD_DBL_SIZE == _RWSTD_INT_SIZE
sl@0
   758
    typedef int IntT;
sl@0
   759
    const IntT imin = _RWSTD_INT_MIN;
sl@0
   760
#elif _RWSTD_DBL_SIZE == _RWSTD_LONG_SIZE
sl@0
   761
    typedef long IntT;
sl@0
   762
    const IntT imin = _RWSTD_LONG_MIN;
sl@0
   763
#elif _RWSTD_DBL_SIZE == _RWSTD_LLONG_SIZE
sl@0
   764
    typedef _RWSTD_LONG_LONG IntT;
sl@0
   765
    const IntT imin = _RWSTD_LLONG_MIN;
sl@0
   766
#endif
sl@0
   767
sl@0
   768
#if _RWSTD_LLONG_SIZE < _RWSTD_DBL_SIZE
sl@0
   769
sl@0
   770
    if (x == y)
sl@0
   771
        return 0;
sl@0
   772
sl@0
   773
    // FIXME: use integer math as in the functions above
sl@0
   774
sl@0
   775
    const double diff = x - y;
sl@0
   776
sl@0
   777
    // check absolute error
sl@0
   778
    if (Abs (diff) < _RWSTD_DBL_EPSILON)
sl@0
   779
        return 0;
sl@0
   780
sl@0
   781
    // check relative error
sl@0
   782
    const double relerr =
sl@0
   783
        Abs (x) < Abs (y) ? Abs (diff / y) : Abs (diff / x);
sl@0
   784
sl@0
   785
    if (relerr <= 0.0000001)
sl@0
   786
        return 0;
sl@0
   787
sl@0
   788
    return x < y ? -1 : +1;
sl@0
   789
sl@0
   790
#else   // if !(_RWSTD_LLONG_SIZE < _RWSTD_DBL_SIZE)
sl@0
   791
sl@0
   792
    if (x == y)
sl@0
   793
        return 0;
sl@0
   794
sl@0
   795
    IntT x_int = *(IntT*)&x;
sl@0
   796
    if (x_int < 0)
sl@0
   797
        x_int = imin - x_int;
sl@0
   798
sl@0
   799
    IntT y_int = *(IntT*)&y;
sl@0
   800
    if (y_int < 0)
sl@0
   801
        y_int = imin - y_int;
sl@0
   802
sl@0
   803
    const IntT int_diff = x_int - y_int;
sl@0
   804
sl@0
   805
    return int_diff;
sl@0
   806
sl@0
   807
#endif   // _RWSTD_LLONG_SIZE < _RWSTD_DBL_SIZE
sl@0
   808
sl@0
   809
}
sl@0
   810
sl@0
   811
sl@0
   812
#ifndef _RWSTD_NO_LONG_DOUBLE
sl@0
   813
_TEST_EXPORT int
sl@0
   814
rw_ldblcmp (long double x, long double y)
sl@0
   815
{
sl@0
   816
    if (sizeof (long double) == sizeof (double))
sl@0
   817
        return rw_dblcmp (double (x), double (y));
sl@0
   818
sl@0
   819
    #ifdef __ARMCC__
sl@0
   820
    #pragma diag_suppress 111
sl@0
   821
    #endif
sl@0
   822
    if (x == y)
sl@0
   823
        return 0;
sl@0
   824
    
sl@0
   825
    
sl@0
   826
sl@0
   827
    // FIXME: use integer math as in the functions above
sl@0
   828
sl@0
   829
    const long double diff = x - y;
sl@0
   830
sl@0
   831
    // check absolute error
sl@0
   832
    if (Abs (diff) < _RWSTD_LDBL_EPSILON)
sl@0
   833
        return 0;
sl@0
   834
sl@0
   835
    // check relative error
sl@0
   836
    const long double relerr =
sl@0
   837
        Abs (x) < Abs (y) ? Abs (diff / y) : Abs (diff / x);
sl@0
   838
sl@0
   839
    if (relerr <= 0.0000001L)
sl@0
   840
        return 0;
sl@0
   841
sl@0
   842
    return x < y ? -1 : +1;
sl@0
   843
}
sl@0
   844
sl@0
   845
#endif   // _RWSTD_NO_LONG_DOUBLE
sl@0
   846
sl@0
   847
#ifdef __SYMBIAN32__
sl@0
   848
_TEST_EXPORT int 
sl@0
   849
 rw_strcmp (std::basic_string<char>& x ,/*std::basic_string<char> */ long double  y)
sl@0
   850
 {
sl@0
   851
   const char * c= x.c_str(); 
sl@0
   852
   
sl@0
   853
   /*if(x.compare(y)==0)
sl@0
   854
       return 0;
sl@0
   855
   else
sl@0
   856
     return x.compare(y)<0?-1:+1;	      */
sl@0
   857
   float z=atof(c);
sl@0
   858
   
sl@0
   859
   if ((long double)z == y)
sl@0
   860
        return 0;
sl@0
   861
sl@0
   862
    // FIXME: use integer math as in the functions above
sl@0
   863
sl@0
   864
    const long double diff =((long double)z) - y;
sl@0
   865
sl@0
   866
    // check absolute error
sl@0
   867
    if (Abs (diff) < _RWSTD_LDBL_EPSILON)
sl@0
   868
        return 0;
sl@0
   869
sl@0
   870
    // check relative error
sl@0
   871
    const long double relerr =
sl@0
   872
        Abs ((long double)z) < Abs (y) ? Abs (diff / y) : Abs (diff /(long double)z);
sl@0
   873
sl@0
   874
    if (relerr <= 0.0000001L)
sl@0
   875
        return 0;
sl@0
   876
sl@0
   877
    return z < y ? -1 : +1;
sl@0
   878
     
sl@0
   879
 }
sl@0
   880
 
sl@0
   881
_TEST_EXPORT int 
sl@0
   882
 rw_strcmp (std::basic_string<wchar_t>& x ,long double y)
sl@0
   883
{
sl@0
   884
 /*  if(x.compare(y)==0)
sl@0
   885
       return 0;
sl@0
   886
   else
sl@0
   887
     return x.compare(y)<0?-1:+1;	      */
sl@0
   888
  
sl@0
   889
 int len=x.length();
sl@0
   890
 const wchar_t *w=x.c_str();
sl@0
   891
 char c[128];
sl@0
   892
 WCtoC(w,len,c);
sl@0
   893
 
sl@0
   894
  float z=atof(c);
sl@0
   895
   
sl@0
   896
   if ((long double)z == y)
sl@0
   897
        return 0;
sl@0
   898
sl@0
   899
    // FIXME: use integer math as in the functions above
sl@0
   900
sl@0
   901
    const long double diff =((long double)z) - y;
sl@0
   902
sl@0
   903
    // check absolute error
sl@0
   904
    if (Abs (diff) < _RWSTD_LDBL_EPSILON)
sl@0
   905
        return 0;
sl@0
   906
sl@0
   907
    // check relative error
sl@0
   908
    const long double relerr =
sl@0
   909
        Abs ((long double)z) < Abs (y) ? Abs (diff / y) : Abs (diff /(long double)z);
sl@0
   910
sl@0
   911
    if (relerr <= 0.0000001L)
sl@0
   912
        return 0;
sl@0
   913
sl@0
   914
    return z < y ? -1 : +1;      
sl@0
   915
     
sl@0
   916
 }   
sl@0
   917
_TEST_EXPORT
sl@0
   918
 void WCtoC(const wchar_t *wstr, int len, char* str)
sl@0
   919
{
sl@0
   920
sl@0
   921
	int i = 0;
sl@0
   922
	for (;i<len;i++)
sl@0
   923
		str[i] = wstr[i]; 
sl@0
   924
sl@0
   925
}
sl@0
   926
sl@0
   927
sl@0
   928
 #endif