diff -r e20de85af2ee -r ce057bb09d0b stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/valcmp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/valcmp.cpp Fri Jun 04 16:20:51 2010 +0100 @@ -0,0 +1,928 @@ + + +/************************************************************************ + * + * valcmp.cpp - definitions of the rw_valcmp() family of helper functions + * + * $Id: valcmp.cpp 332687 2005-11-12 00:47:57Z sebor $ + * + ************************************************************************ + * + * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave + * Software division. Licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. Unless required by + * applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License + * for the specific language governing permissions and limitations under + * the License. + * + **************************************************************************/ + +// expand _TEST_EXPORT macros +#define _RWSTD_TEST_SRC + +#include +#include + +#include // for fprintf, stderr +#include // for abort +#include // for memcmp + +/**************************************************************************/ + +typedef unsigned char UChar; + + +static const UChar +_rw_upper [] = { + +#if 'A' == 0x41 + + // basic ASCII: + // .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f + // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- + // NUL SOH STX ETX EOT ENQ ACK BEL BS TAB LF VT FF CR SO SI + /* 0. */ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + // DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US + /* 1. */ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + // SPC ! " # $ % ' ' ( ) * + , - . / + /* 2. */ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" + // 0 1 2 3 4 5 6 7 8 9 : ; < = > ? + /* 3. */ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" + // A B C D E F G H I J K L M N O + /* 4. */ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" + // P Q R S T U V W X Y Z [ \ ] ^ _ + /* 5. */ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" + // ` a b c d e f g h i j k l m n o + /* 6. */ "\x60\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" + // p q r s t u v w x y z { | } ~ DEL + /* 7. */ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x7b\x7c\x7d\x7e\x7f" + + // extended ASCII: + /* 8. */ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" + /* 9. */ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" + /* a. */ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" + /* b. */ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" + /* c. */ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" + /* d. */ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" + /* e. */ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" + /* f. */ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" + +#elif 'A' == 0xc1 + + // EBCDIC: + // .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f + // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- + // NUL SOH STX ETX PF HT LC DEL SMM VT FF CR SO SI + /* 0. */ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + // DLE DC1 DC2 TM RES NL BS IL CAN EM CC CU1 IFS IGS IRS IUS + /* 1. */ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + // DS SOS FS BYP LF ETB ESC SM CU2 ENQ ACK BEL + /* 2. */ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" + // SYN PN RS UC EOT CU3 DC4 NAK SUB + /* 3. */ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" + // SP ct. . < ( + | + /* 4. */ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" + // & ! $ * ) ; ~ + /* 5. */ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" + // - / , % _ > ? + /* 6. */ "\x60\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" + // : # @ ' = " + /* 7. */ "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" + // a b c d e f g h i + /* 8. */ "\x80\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\x8a\x8b\x8c\x8d\x8e\x8f" + // j k l m n o p q r + /* 9. */ "\x90\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\x9a\x9b\x9c\x9d\x9e\x9f" + // s t u v w x y z + /* a. */ "\xa0\xa1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xaa\xab\xac\xad\xae\xaf" + // ` + /* b. */ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" + // A B C D E F G H I + /* c. */ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" + // J K L M N O P Q R + /* d. */ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" + // S T U V W X Y Z + /* e. */ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" + // 0 1 2 3 4 5 6 7 8 9 + /* f. */ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" + +#else // 'A' != 0x41 && 'A' != 0xc1 +# error unknown character set (neither ASCII nor EBCDIC) +#endif // ASCII or EBCDIC + +}; + + +// returns 1 iff all size bytes of the object pointed to by buf are 0 +static int +_rw_iszero (const void *buf, _RWSTD_SIZE_T size) +{ + for (_RWSTD_SIZE_T i = 0; i != size; ++i) + if (_RWSTD_STATIC_CAST (const UChar*, buf)[i]) + return 0; + + return 1; +} + + +// compares two objects of equal size +static int +_rw_cmpx (const void *buf1, + const void *buf2, + _RWSTD_SIZE_T nelems, + _RWSTD_SIZE_T size, + int flags = 0) +{ + const UChar *p1 = _RWSTD_STATIC_CAST (const UChar*, buf1); + const UChar *p2 = _RWSTD_STATIC_CAST (const UChar*, buf2); + + int ret = 0; + + for ( ; nelems; p1 += size, p2 += size, --nelems) { + + ret = memcmp (p1, p2, size); + + if (flags & CMP_NULTERM) { + + const int zero1 = _rw_iszero (p1, size); + const int zero2 = _rw_iszero (p2, size); + + if (zero1 || zero2) { + ret = zero1 - zero2; + break; + } + } + + if (ret && (flags & CMP_NOCASE)) { + // FIXME: implement + fprintf (stderr, + "%s:%d: case insensitive comparison not implemented\n", + __FILE__, __LINE__); + abort (); + } + } + + if (flags & CMP_RETOFF) { + // FIXME: implement + fprintf (stderr, + "%s:%d: returning offset not implemented\n", + __FILE__, __LINE__); + abort (); + } + + return ret < 0 ? -1 : ret ? +1 : 0; +} + + +// compares two byte arrays +static int +_rw_cmp1 (const void *buf1, + const void *buf2, + _RWSTD_SIZE_T nelems, + int flags = 0) +{ +#ifdef _RWSTD_UINT8_T + + typedef _RWSTD_UINT8_T UI8T; + + if (0 == flags) { + const int ret = memcmp (buf1, buf2, nelems); + return ret < 0 ? -1 : ret ? +1 : 0; + } + + if (CMP_NULTERM == flags) { + const int ret = + strncmp (_RWSTD_STATIC_CAST (const char*, buf1), + _RWSTD_STATIC_CAST (const char*, buf2), + nelems); + return ret < 0 ? -1 : ret ? +1 : 0; + } + + int ret = 0; + int inx = 0; + + const UI8T *pi1 = _RWSTD_STATIC_CAST (const UI8T*, buf1); + const UI8T *pi2 = _RWSTD_STATIC_CAST (const UI8T*, buf2); + + for (; nelems; ++pi1, ++pi2, --nelems, ++inx) { + + const UI8T ui1 = *pi1; + const UI8T ui2 = *pi2; + + if (flags & CMP_NULTERM) { + + if (0 == ui1) { + ret = ui2 ? -1 : 0; + break; + } + + if (0 == ui2) { + ret = +1; + break; + } + } + + if (ui1 != ui2) { + if (flags & CMP_NOCASE) { + if (_rw_upper [ui1] != _rw_upper [ui2]) { + ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1; + break; + } + } + else { + ret = ui1 < ui2 ? -1 : +1; + break; + } + } + } + + if (CMP_RETOFF & flags) { + ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1; + } + + return ret; + +#else // if !defined (_RWSTD_UINT8_T) +# error _RWSTD_UINT8_T not #defined (configuration problem?) +#endif // _RWSTD_UINT8_T + +} + + +// compares two arrays of objects each 16 bits in size +static int +_rw_cmp2 (const void *buf1, + const void *buf2, + _RWSTD_SIZE_T nelems, + int flags = 0) +{ +#ifdef _RWSTD_UINT16_T + + typedef _RWSTD_UINT16_T UI16T; + + int ret = 0; + int inx = 0; + + const UI16T *pi1 = _RWSTD_STATIC_CAST (const UI16T*, buf1); + const UI16T *pi2 = _RWSTD_STATIC_CAST (const UI16T*, buf2); + + for (; nelems; ++pi1, ++pi2, --nelems) { + + const UI16T ui1 = *pi1; + const UI16T ui2 = *pi2; + + if (flags & CMP_NULTERM) { + + if (0 == ui1) { + ret = ui2 ? -1 : 0; + break; + } + + if (0 == ui2) { + ret = +1; + break; + } + } + + if (ui1 != ui2) { + if (flags & CMP_NOCASE) { + if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) { + ret = ui1 < ui2 ? -1 : +1; + break; + } + else if (_rw_upper [ui1] != _rw_upper [ui2]) { + ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1; + break; + } + } + else { + ret = ui1 < ui2 ? -1 : +1; + break; + } + } + } + + if (CMP_RETOFF & flags) { + ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1; + } + + return ret; + +#else // if !defined (_RWSTD_UINT16_T) + + return _rw_cmpx (buf1, buf2, nelems, 2, flags); + +#endif // _RWSTD_UINT16_T +} + + +// compares two arrays of objects each 32 bits in size +static int +_rw_cmp4 (const void *buf1, + const void *buf2, + _RWSTD_SIZE_T nelems, + int flags = 0) +{ +#ifdef _RWSTD_UINT32_T + + typedef _RWSTD_UINT32_T UI32T; + + int ret = 0; + int inx = 0; + + const UI32T *pi1 = _RWSTD_STATIC_CAST (const UI32T*, buf1); + const UI32T *pi2 = _RWSTD_STATIC_CAST (const UI32T*, buf2); + + for (; nelems; ++pi1, ++pi2, --nelems) { + + const UI32T ui1 = *pi1; + const UI32T ui2 = *pi2; + + if (flags & CMP_NULTERM) { + + if (0 == ui1) { + ret = ui2 ? -1 : 0; + break; + } + + if (0 == ui2) { + ret = +1; + break; + } + } + + if (ui1 != ui2) { + if (flags & CMP_NOCASE) { + if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) { + ret = ui1 < ui2 ? -1 : +1; + break; + } + else if (_rw_upper [ui1] != _rw_upper [ui2]) { + ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1; + break; + } + } + else { + ret = ui1 < ui2 ? -1 : +1; + break; + } + } + } + + if (CMP_RETOFF & flags) { + ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1; + } + + return ret; + +#else // if !defined (_RWSTD_UINT32_T) + + return _rw_cmpx (buf1, buf2, nelems, 4, flags); + +#endif // _RWSTD_UINT32_T +} + + +// compares two arrays of objects each 64 bits in size +static int +_rw_cmp8 (const void *buf1, + const void *buf2, + _RWSTD_SIZE_T nelems, + int flags = 0) +{ +#ifdef _RWSTD_UINT64_T + + typedef _RWSTD_UINT64_T UI64T; + + int ret = 0; + int inx = 0; + + const UI64T *pi1 = _RWSTD_STATIC_CAST (const UI64T*, buf1); + const UI64T *pi2 = _RWSTD_STATIC_CAST (const UI64T*, buf2); + + for (; nelems; ++pi1, ++pi2, --nelems) { + + const UI64T ui1 = *pi1; + const UI64T ui2 = *pi2; + + if (flags & CMP_NULTERM) { + + if (0 == ui1) { + ret = ui2 ? -1 : 0; + break; + } + + if (0 == ui2) { + ret = +1; + break; + } + } + + if (ui1 != ui2) { + if (flags & CMP_NOCASE) { + if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) { + ret = ui1 < ui2 ? -1 : +1; + break; + } + else if (_rw_upper [ui1] != _rw_upper [ui2]) { + ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1; + break; + } + } + else { + ret = ui1 < ui2 ? -1 : +1; + break; + } + } + } + + if (CMP_RETOFF & flags) { + ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1; + } + + return ret; + +#else // if !defined (_RWSTD_UINT64_T) + + return _rw_cmpx (buf1, buf2, nelems, 8, flags); + +#endif // _RWSTD_UINT64_T +} + + +// compares two arrays of objects of unequal size +static int +_rw_cmpxx (const void* buf1, + const void* buf2, + _RWSTD_SIZE_T nelems, + _RWSTD_SIZE_T size1, + _RWSTD_SIZE_T size2, + int flags) +{ + int ret = 0; + int inx = 0; + + for (; nelems; --nelems, ++inx) { + +#ifdef _RWSTD_UINT64_T + + _RWSTD_UINT64_T ui1; + _RWSTD_UINT64_T ui2; + +#else // if !defined (_RWSTD_UINT64_T) + + _RWSTD_SIZE_T ui1; + _RWSTD_SIZE_T ui2; + +#endif // _RWSTD_UINT64_T + + switch (size1) { + +#ifdef _RWSTD_UINT8_T + + case 1: { + const _RWSTD_UINT8_T* ptr = + _RWSTD_STATIC_CAST (const _RWSTD_UINT8_T*, buf1); + ui1 = *ptr++; + buf1 = ptr; + break; + } + +#endif // _RWSTD_UINT8_T + +#ifdef _RWSTD_UINT16_T + + case 2: { + const _RWSTD_UINT16_T* ptr = + _RWSTD_STATIC_CAST (const _RWSTD_UINT16_T*, buf1); + ui1 = *ptr++; + buf1 = ptr; + break; + } + +#endif // _RWSTD_UINT16_T + +#ifdef _RWSTD_UINT32_T + + case 4: { + const _RWSTD_UINT32_T* ptr = + _RWSTD_STATIC_CAST (const _RWSTD_UINT32_T*, buf1); + ui1 = *ptr++; + buf1 = ptr; + break; + } + +#endif // _RWSTD_UINT32_T + +#ifdef _RWSTD_UINT64_T + + case 8: { + const _RWSTD_UINT64_T* ptr = + _RWSTD_STATIC_CAST (const _RWSTD_UINT64_T*, buf1); + ui1 = *ptr++; + buf1 = ptr; + break; + } + +#endif // _RWSTD_UINT64_T + + default: + fprintf (stderr, + "%s:%d: comparison of objects %u and %u bytes in size " + "not implemented\n", __FILE__, __LINE__, + unsigned (size1), unsigned (size2)); + abort (); + } + + switch (size2) { + +#ifdef _RWSTD_UINT8_T + + case 1: { + const _RWSTD_UINT8_T* ptr = + _RWSTD_STATIC_CAST (const _RWSTD_UINT8_T*, buf2); + ui2 = *ptr++; + buf2 = ptr; + break; + } + +#endif // _RWSTD_UINT8_T + +#ifdef _RWSTD_UINT16_T + + case 2: { + const _RWSTD_UINT16_T* ptr = + _RWSTD_STATIC_CAST (const _RWSTD_UINT16_T*, buf2); + ui2 = *ptr++; + buf2 = ptr; + break; + } + +#endif // _RWSTD_UINT16_T + +#ifdef _RWSTD_UINT32_T + + case 4: { + const _RWSTD_UINT32_T* ptr = + _RWSTD_STATIC_CAST (const _RWSTD_UINT32_T*, buf2); + ui2 = *ptr++; + buf2 = ptr; + break; + } + +#endif // _RWSTD_UINT32_T + +#ifdef _RWSTD_UINT64_T + + case 8: { + const _RWSTD_UINT64_T* ptr = + _RWSTD_STATIC_CAST (const _RWSTD_UINT64_T*, buf2); + ui2 = *ptr++; + buf2 = ptr; + break; + } + +#endif // _RWSTD_UINT64_T + + default: + fprintf (stderr, + "%s:%d: comparison of objects %u and %u bytes in size " + "not implemented\n", __FILE__, __LINE__, + unsigned (size1), unsigned (size2)); + abort (); + } + + if (flags & CMP_NULTERM) { + + if (0 == ui1) { + ret = ui2 ? -1 : 0; + break; + } + + if (0 == ui2) { + ret = +1; + break; + } + } + + if (ui1 != ui2) { + if (flags & CMP_NOCASE) { + if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) { + ret = ui1 < ui2 ? -1 : +1; + break; + } + else if (_rw_upper [ui1] != _rw_upper [ui2]) { + ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1; + break; + } + } + else { + ret = ui1 < ui2 ? -1 : +1; + break; + } + } + } + + if (CMP_RETOFF & flags) { + ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1; + } + + return ret; +} + + +_TEST_EXPORT int +rw_valcmp (const void* buf1, + const void* buf2, + _RWSTD_SIZE_T nelems, + _RWSTD_SIZE_T size1, + _RWSTD_SIZE_T size2, + int flags /* = 0 */) +{ + if (size1 == size2) { + + switch (size1) { + case 1: return _rw_cmp1 (buf1, buf2, nelems, flags); + case 2: return _rw_cmp2 (buf1, buf2, nelems, flags); + case 4: return _rw_cmp4 (buf1, buf2, nelems, flags); + case 8: return _rw_cmp8 (buf1, buf2, nelems, flags); + } + + return _rw_cmpx (buf1, buf2, nelems, size1, flags); + } + + return _rw_cmpxx (buf1, buf2, nelems, size1, size2, flags); +} + + +_TEST_EXPORT int +rw_strncmp (const char* str1, + const char* str2, + _RWSTD_SIZE_T nelems /* = _RWSTD_SIZE_MAX */, + int flags /* = CMP_NULTERM */) +{ + return rw_valcmp (str1, str2, nelems, 1, 1, flags); +} + + +#ifndef _RWSTD_NO_WCHAR_T + +_TEST_EXPORT int +rw_strncmp (const char* str1, + const wchar_t* str2, + _RWSTD_SIZE_T nelems /* = _RWSTD_SIZE_MAX */, + int flags /* = CMP_NULTERM */) +{ + return rw_valcmp (str1, str2, nelems, 1, sizeof (wchar_t), flags); +} + + +_TEST_EXPORT int +rw_strncmp (const wchar_t* str1, + const char* str2, + _RWSTD_SIZE_T nelems /* = _RWSTD_SIZE_MAX */, + int flags /* = CMP_NULTERM */) +{ + return rw_valcmp (str1, str2, nelems, sizeof (wchar_t), 1, flags); +} + + +_TEST_EXPORT int +rw_strncmp (const wchar_t* str1, + const wchar_t* str2, + _RWSTD_SIZE_T nelems /* = _RWSTD_SIZE_MAX */, + int flags /* = CMP_NULTERM */) +{ + return rw_valcmp (str1, str2, nelems, + sizeof (wchar_t), sizeof (wchar_t), flags); +} + +#endif // _RWSTD_NO_WCHAR_T + + +// floating point comparison helpers based on +// http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm + +_TEST_EXPORT int +rw_fltcmp (float x, float y) +{ +#if _RWSTD_SHRT_SIZE == _RWSTD_INT_SIZE + typedef short IntT; + #ifdef __ARMCC__ + #pragma diag_suppress 68 + #endif + const IntT imin = _RWSTD_SHRT_MIN; + +#elif _RWSTD_FLT_SIZE == _RWSTD_INT_SIZE + typedef int IntT; + const IntT imin = _RWSTD_INT_MIN; +#elif _RWSTD_FLT_SIZE == _RWSTD_LONG_SIZE + typedef long IntT; + const IntT imin = _RWSTD_LONG_MIN; +#elif _RWSTD_FLT_SIZE == _RWSTD_LLONG_SIZE + typedef _RWSTD_LONG_LONG IntT; + const IntT imin = _RWSTD_LLONG_MIN; +#else + // ??? +# error no integral type of the same size as float exists +#endif + + if (x == y) + return 0; + + // make both arguments lexicographically ordered as twos-complement ints + IntT x_int = *(IntT*)&x; + if (x_int < 0) + x_int = imin - x_int; + + IntT y_int = *(IntT*)&y; + if (y_int < 0) + y_int = imin - y_int; + + const IntT int_diff = x_int - y_int; + + return int_diff; +} + + +#define Abs(x) ((x) < 0 ? -(x) : (x)) + + +_TEST_EXPORT int +rw_dblcmp (double x, double y) +{ +#if _RWSTD_DBL_SIZE == _RWSTD_INT_SIZE + typedef int IntT; + const IntT imin = _RWSTD_INT_MIN; +#elif _RWSTD_DBL_SIZE == _RWSTD_LONG_SIZE + typedef long IntT; + const IntT imin = _RWSTD_LONG_MIN; +#elif _RWSTD_DBL_SIZE == _RWSTD_LLONG_SIZE + typedef _RWSTD_LONG_LONG IntT; + const IntT imin = _RWSTD_LLONG_MIN; +#endif + +#if _RWSTD_LLONG_SIZE < _RWSTD_DBL_SIZE + + if (x == y) + return 0; + + // FIXME: use integer math as in the functions above + + const double diff = x - y; + + // check absolute error + if (Abs (diff) < _RWSTD_DBL_EPSILON) + return 0; + + // check relative error + const double relerr = + Abs (x) < Abs (y) ? Abs (diff / y) : Abs (diff / x); + + if (relerr <= 0.0000001) + return 0; + + return x < y ? -1 : +1; + +#else // if !(_RWSTD_LLONG_SIZE < _RWSTD_DBL_SIZE) + + if (x == y) + return 0; + + IntT x_int = *(IntT*)&x; + if (x_int < 0) + x_int = imin - x_int; + + IntT y_int = *(IntT*)&y; + if (y_int < 0) + y_int = imin - y_int; + + const IntT int_diff = x_int - y_int; + + return int_diff; + +#endif // _RWSTD_LLONG_SIZE < _RWSTD_DBL_SIZE + +} + + +#ifndef _RWSTD_NO_LONG_DOUBLE +_TEST_EXPORT int +rw_ldblcmp (long double x, long double y) +{ + if (sizeof (long double) == sizeof (double)) + return rw_dblcmp (double (x), double (y)); + + #ifdef __ARMCC__ + #pragma diag_suppress 111 + #endif + if (x == y) + return 0; + + + + // FIXME: use integer math as in the functions above + + const long double diff = x - y; + + // check absolute error + if (Abs (diff) < _RWSTD_LDBL_EPSILON) + return 0; + + // check relative error + const long double relerr = + Abs (x) < Abs (y) ? Abs (diff / y) : Abs (diff / x); + + if (relerr <= 0.0000001L) + return 0; + + return x < y ? -1 : +1; +} + +#endif // _RWSTD_NO_LONG_DOUBLE + +#ifdef __SYMBIAN32__ +_TEST_EXPORT int + rw_strcmp (std::basic_string& x ,/*std::basic_string */ long double y) + { + const char * c= x.c_str(); + + /*if(x.compare(y)==0) + return 0; + else + return x.compare(y)<0?-1:+1; */ + float z=atof(c); + + if ((long double)z == y) + return 0; + + // FIXME: use integer math as in the functions above + + const long double diff =((long double)z) - y; + + // check absolute error + if (Abs (diff) < _RWSTD_LDBL_EPSILON) + return 0; + + // check relative error + const long double relerr = + Abs ((long double)z) < Abs (y) ? Abs (diff / y) : Abs (diff /(long double)z); + + if (relerr <= 0.0000001L) + return 0; + + return z < y ? -1 : +1; + + } + +_TEST_EXPORT int + rw_strcmp (std::basic_string& x ,long double y) +{ + /* if(x.compare(y)==0) + return 0; + else + return x.compare(y)<0?-1:+1; */ + + int len=x.length(); + const wchar_t *w=x.c_str(); + char c[128]; + WCtoC(w,len,c); + + float z=atof(c); + + if ((long double)z == y) + return 0; + + // FIXME: use integer math as in the functions above + + const long double diff =((long double)z) - y; + + // check absolute error + if (Abs (diff) < _RWSTD_LDBL_EPSILON) + return 0; + + // check relative error + const long double relerr = + Abs ((long double)z) < Abs (y) ? Abs (diff / y) : Abs (diff /(long double)z); + + if (relerr <= 0.0000001L) + return 0; + + return z < y ? -1 : +1; + + } +_TEST_EXPORT + void WCtoC(const wchar_t *wstr, int len, char* str) +{ + + int i = 0; + for (;i