📄 yc_function.c
字号:
/*
* The young Library
* Copyright (c) 2005 by Yang Huan(杨桓)
* Permission to use, copy, modify, distribute and sell this software for any
* purpose is hereby granted without fee, provided that the above copyright
* notice appear in all copies and that both that copyright notice and this
* permission notice appear in supporting documentation.
* The author make no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
*/
/******************************************************************************/
/******************************************************************************/
#include <limits.h>
#include <math.h>
#include <float.h>
#include <string.h>
#include "yc_function.h"
#ifdef __cplusplus
namespace youngc { extern "C" {
#endif
/******************************************************************************/
/******************************************************************************/
#define HASH_COMBINE(h, v) ( h ^= (size_t)v + 0x9e3779b9 + (h<<6) + (h>>2) )
#define HASH_TEMPLATE( FunName, Type ) \
size_t FunName( const void* x ) \
{ \
return (size_t)( *((Type*)x) ); \
}
#define COMPARE_TEMPLATE( FunName, Type ) \
int FunName( const void* left, const void* right ) \
{ \
Type x = *( (Type*)left ); \
Type y = *( (Type*)right ); \
if( x < y ) \
return -1; \
else if( x > y ) \
return 1; \
else \
return 0; \
}
/******************************************************************************/
HASH_TEMPLATE( hash_char, unsigned char )
HASH_TEMPLATE( hash_short, unsigned short )
HASH_TEMPLATE( hash_int, unsigned int )
HASH_TEMPLATE( hash_long, unsigned long )
#ifdef __MACRO_C_YOUNG_LIBRARY_COMPILER_SUPPORT_LONG_LONG_TYPE__
HASH_TEMPLATE( hash_llong, unsigned long long )
#endif
size_t hash_str( const void* str )
{
size_t h = 0;
char* s = (char*)str;
for( ; *s; ++s )
h = (h << 5) - h + *s;
return h;
}
size_t hash_wstr( const void* wstr )
{
size_t h = 0;
wchar_t* ws = (wchar_t*)wstr;
for( ; *ws; ++ws )
h = (h << 5) - h + *ws;
return h;
}
size_t hash_float( const void* x )
{
float f = *( (float*)x );
int part, exp = 0, intbits = sizeof(int) * CHAR_BIT - 1;
size_t h = 0, len = ( FLT_MANT_DIG + intbits - 1 ) / intbits;
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
f = frexpf( f, &exp );
#else
f = (float)frexp( f, &exp );
#endif
for( ; len > 0; --len )
{
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
f = ldexpf( f, intbits );
#else
f = (float)ldexp( f, intbits );
#endif
part = (int)f;
f -= part;
HASH_COMBINE( h, part );
}
HASH_COMBINE( h, exp );
return h;
}
size_t hash_double( const void* x )
{
double df = *( (double*)x );
int part, exp = 0, intbits = sizeof(int) * CHAR_BIT - 1;
size_t h = 0, len = ( DBL_MANT_DIG + intbits - 1 ) / intbits;
df = frexp( df, &exp );
for( ; len > 0; --len )
{
df = ldexp( df, intbits );
part = (int)df;
df -= part;
HASH_COMBINE( h, part );
}
HASH_COMBINE( h, exp );
return h;
}
size_t hash_ldouble( const void* x )
{
long double ldf = *( (long double*)x );
int part, exp = 0, intbits = sizeof(int) * CHAR_BIT - 1;
size_t h = 0, len = ( LDBL_MANT_DIG + intbits - 1 ) / intbits;
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
ldf = frexpl( ldf, &exp );
#else
ldf = (long double)frexp( (double)ldf, &exp );
#endif
for( ; len > 0; --len )
{
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
ldf = ldexpl( ldf, intbits );
#else
ldf = (long double)ldexp( (double)ldf, intbits );
#endif
part = (int)ldf;
ldf -= part;
HASH_COMBINE( h, part );
}
HASH_COMBINE( h, exp );
return h;
}
/******************************************************************************/
COMPARE_TEMPLATE( cmp_char, char )
COMPARE_TEMPLATE( cmp_uchar, unsigned char )
COMPARE_TEMPLATE( cmp_short, short )
COMPARE_TEMPLATE( cmp_ushort, unsigned short )
COMPARE_TEMPLATE( cmp_int, int )
COMPARE_TEMPLATE( cmp_uint, unsigned int )
COMPARE_TEMPLATE( cmp_long, long )
COMPARE_TEMPLATE( cmp_ulong, unsigned long )
#ifdef __MACRO_C_YOUNG_LIBRARY_COMPILER_SUPPORT_LONG_LONG_TYPE__
COMPARE_TEMPLATE( cmp_llong, long long )
COMPARE_TEMPLATE( cmp_ullong, unsigned long long )
#endif
COMPARE_TEMPLATE( cmp_float, float )
COMPARE_TEMPLATE( cmp_double, double )
COMPARE_TEMPLATE( cmp_ldouble, long double )
int cmp_str( const void* left, const void* right )
{
return strcmp( (const char*)left, (const char*)right );
}
int cmp_wstr( const void* left, const void* right )
{
int result = 0;
const wchar_t* ls = (const wchar_t*)left;
const wchar_t* rs = (const wchar_t*)right;
for( ; *ls && *rs; ++ls,++rs )
{
if( *ls != *rs )
{
result = *ls < *rs ? -1 : 1;
break;
}
}
if( 0 == result )
{
if( *ls && !(*rs) )
result = 1;
else if( !(*ls) && *rs )
result = -1;
}
return result;
}
/******************************************************************************/
/******************************************************************************/
#ifdef __cplusplus
} }
#endif
/******************************************************************************/
/******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -