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