00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#ifndef __NESTEDSUMS_UTILS_H__
00027
#define __NESTEDSUMS_UTILS_H__
00028
00029
#include <typeinfo>
00030
00031
#include "ginac/ginac.h"
00032
00033
#include "config.h"
00034
00035
namespace nestedsums {
00036
00037
00038
00041 inline unsigned rotate_left_31(
unsigned n)
00042 {
00043
00044 n = (n & 0x7FFFFFFFU) << 1;
00045
00046
00047
if (n & 0x80000000U)
00048 n = (n & 0x7FFFFFFFU) | 0x00000001U;
00049
00050 GINAC_ASSERT(n<0x80000000U);
00051
00052
return n;
00053 }
00054
00055
#if SIZEOF_VOID_P == SIZEOF_INT
00056
typedef unsigned int p_int;
00057
#elif SIZEOF_VOID_P == SIZEOF_LONG
00058
typedef unsigned long p_int;
00059
#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG
00060
typedef unsigned long long p_int;
00061
#else
00062
typedef unsigned long p_int;
00063
#endif
00064
00066 inline unsigned golden_ratio_hash(
unsigned n)
00067 {
00068
00069
#if SIZEOF_LONG >= 8
00070
00071
00072
unsigned long l = n * 0x4f1bbcddL;
00073
return (l & 0x7fffffffU) ^ (l >> 32);
00074
#elif SIZEOF_LONG_LONG >= 8
00075
00076
00077
00078
unsigned long long l = n * 0x4f1bbcddL;
00079
return (l & 0x7fffffffU) ^ (l >> 32);
00080
#elif SIZEOF_LONG_DOUBLE > 8
00081
00082
00083
00084
const static long double golden_ratio = .618033988749894848204586834370;
00085
long double m = golden_ratio * n;
00086
return unsigned((m -
int(m)) * 0x80000000);
00087
#else
00088
#error "No 64 bit data type. You lose."
00089
#endif
00090
}
00091
00092
static inline unsigned make_hash_seed(
const std::type_info& tinfo)
00093 {
00094
00095
00096
const void* mangled_name_ptr = (
const void*)tinfo.name();
00097
unsigned v =
golden_ratio_hash((p_int)mangled_name_ptr);
00098
return v;
00099 }
00100
00101
00102 }
00103
00104
#endif // ndef __NESTEDSUMS_UTILS_H__
00105