Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members

utils.h

Go to the documentation of this file.
00001 00008 /* 00009 * Copyright (C) 2001 Stefan Weinzierl 00010 * 00011 * This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software 00023 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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 // some functions stolen from GiNaC: 00038 00041 inline unsigned rotate_left_31(unsigned n) 00042 { 00043 // clear highest bit and shift 1 bit to the left 00044 n = (n & 0x7FFFFFFFU) << 1; 00045 00046 // overflow? clear highest bit and set lowest bit 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 // This function requires arithmetic with at least 64 significant bits 00069 #if SIZEOF_LONG >= 8 00070 // So 'long' has 64 bits. Excellent! We prefer it because it might be 00071 // more efficient than 'long long'. 00072 unsigned long l = n * 0x4f1bbcddL; 00073 return (l & 0x7fffffffU) ^ (l >> 32); 00074 #elif SIZEOF_LONG_LONG >= 8 00075 // This requires 'long long' (or an equivalent 64 bit type)---which is, 00076 // unfortunately, not ANSI-C++-compliant. 00077 // (Yet C99 demands it, which is reason for hope.) 00078 unsigned long long l = n * 0x4f1bbcddL; 00079 return (l & 0x7fffffffU) ^ (l >> 32); 00080 #elif SIZEOF_LONG_DOUBLE > 8 00081 // If 'long double' is bigger than 64 bits, we assume that the mantissa 00082 // has at least 64 bits. This is not guaranteed but it's a good guess. 00083 // Unfortunately, it may lead to horribly slow code. 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 // this pointer is the same for all objects of the same type. 00095 // Hence we can use that pointer 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 } // namespace nestedsums 00103 00104 #endif // ndef __NESTEDSUMS_UTILS_H__ 00105

Generated on Wed Jun 10 22:59:10 2009 for Nestedsums library by doxygen 1.3.7