00001 /* 00002 * libfid - Full-text Index Data structure library 00003 * Copyright (C) 2006, 2007, 2008, 2009 Robert Homann 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00018 * MA 02110-1301 USA 00019 */ 00020 00021 #ifndef LIBFIDINTTYPES_H 00022 #define LIBFIDINTTYPES_H 00023 /*!\addtogroup integers Integers */ 00024 /*@{*/ 00025 00026 /*!\def fid_WORDSIZE 00027 * \brief The native integer size. 00028 * 00029 * This is defined to either 32 or 64. Its value is figured via feature test 00030 * macros. Types like #fid_Uint64 are defined depending on the value of this 00031 * symbol. 00032 */ 00033 00034 /* 00035 * Figure out architecture word size using feature test macros. 00036 */ 00037 #if defined __LP64__ || defined _LP64 || defined __64BIT__ || (defined __sparc && defined __sparcv9) || defined __x86_64 || defined __amd64 00038 #define fid_WORDSIZE 64 00039 #else /* no 64 bit symbol defined */ 00040 #ifdef __WORDSIZE 00041 #define fid_WORDSIZE __WORDSIZE 00042 #else /* !__WORDSIZE */ 00043 #define fid_WORDSIZE 32 00044 #endif /* __WORDSIZE */ 00045 #endif /* __LP64__ || _LP64 || __64BIT__ */ 00046 00047 /*!\typedef fid_Uint64 00048 * \brief Unsigned 64 bit integer type. */ 00049 /*!\typedef fid_Uint32 00050 * \brief Unsigned 32 bit integer type. */ 00051 /*!\typedef fid_Uint16 00052 * \brief Unsigned 16 bit integer type. */ 00053 /*!\typedef fid_Sint64 00054 * \brief Signed 64 bit integer type. */ 00055 /*!\typedef fid_Sint32 00056 * \brief Signed 32 bit integer type. */ 00057 /*!\typedef fid_Sint16 00058 * \brief Signed 16 bit integer type. */ 00059 /*!\def fid_U64FMT 00060 * \brief Format string for printing a #fid_Uint64 value. 00061 * 00062 * Always use this for printing values of type #fid_Uint64. Never use 00063 * <code>%%lu</code> or <code>%%llu</code> directly for printing a #fid_Uint64 00064 * value. The reason is that #fid_Uint64 may be defined differently on 00065 * different platforms, so there can be no fixed format string that is correct 00066 * on all platforms, 00067 * 00068 * \see also fid_S64FMT. */ 00069 /*!\def fid_S64FMT 00070 * \brief Format string for printing a #fid_Sint64 value. 00071 * 00072 * Always use this for printing values of type #fid_Sint64. 00073 * 00074 * \see also fid_U64FMT. */ 00075 00076 /* 00077 * Define 64 bit integer types fid_Uint64 and fid_Sint64, and format strings 00078 * fid_U64FMT and fid_S64FMT for printing 64 bit integers when cast to 00079 * fid_Uint64 or fid_Sint64, respectively. 00080 */ 00081 #if fid_WORDSIZE == 64 00082 typedef unsigned long fid_Uint64; 00083 typedef signed long fid_Sint64; 00084 #define fid_U64FMT "%lu" 00085 #define fid_S64FMT "%ld" 00086 #elif fid_WORDSIZE == 32 00087 typedef unsigned long long fid_Uint64; 00088 typedef signed long long fid_Sint64; 00089 #define fid_U64FMT "%llu" 00090 #define fid_S64FMT "%lld" 00091 #else /* fid_WORDSIZE != 64 && fid_WORDSIZE != 32 */ 00092 #error Unknown word size. 00093 #endif /* fid_WORDSIZE == 64 || fid_WORDSIZE == 32 */ 00094 00095 /* 00096 * Define 32 bit and 16 bit integer types. These should be used whenever a 00097 * fixed size is required. 00098 */ 00099 typedef unsigned int fid_Uint32; 00100 typedef signed int fid_Sint32; 00101 typedef unsigned short fid_Uint16; 00102 typedef signed short fid_Sint16; 00103 00104 /*! \brief Maximum value of a #fid_Uint64. */ 00105 #define fid_UINT64_MAX ((fid_Uint64)~(fid_Uint64)0) 00106 00107 /*! \brief Maximum value of a #fid_Uint32. */ 00108 #define fid_UINT32_MAX ((fid_Uint32)~(fid_Uint32)0) 00109 00110 /*! \brief Maximum value of a #fid_Uint16. */ 00111 #define fid_UINT16_MAX ((fid_Uint16)~(fid_Uint16)0) 00112 00113 /*! 00114 * \brief Format string for printing a #fid_Uint32 value. 00115 * 00116 * This should be used for printing values of type #fid_Uint32. Raw int values 00117 * or other raw C type values, however, should be printed using their 00118 * respective standard format strings. 00119 * 00120 * \see also fid_S32FMT. 00121 */ 00122 #define fid_U32FMT "%u" 00123 00124 /*! 00125 * \brief Format string for printing a fid_Sint32 value. 00126 * 00127 * This should be used for printing values of type #fid_Sint32. 00128 * 00129 * \see also fid_U32FMT. 00130 */ 00131 #define fid_S32FMT "%d" 00132 00133 /*! 00134 * \brief Format string for printing a table request bitmask. 00135 * 00136 * This should be used for printing values of type #fid_Tablerequest. 00137 */ 00138 #define fid_TABREQFMT "%08x" 00139 00140 /*! 00141 * \brief Type of integers used in some structure, i.e., fid_Uint48. 00142 * 00143 * Some data types, i.e., fid_Uint48 and fid_Suffixarray can store data 00144 * represented by either 32 or 64 bit values. In order to be able to decide 00145 * between these where it is necessary, a type identifier is stored along with 00146 * the data. 00147 * 00148 * Instead of using a simple boolean to switch between 32/64 bit code, we use 00149 * this enumeration. The enumeration begins at 1 in order to catch 00150 * uninitialized values at runtime (indicating a programming error). 00151 * 00152 * \see fid_SWITCH48(). 00153 */ 00154 typedef enum 00155 { 00156 fid_UINTSIZE_UNDEF=1, /*!<\brief Undefined integer size. */ 00157 fid_UINTSIZE_32, /*!<\brief Integer size is 32 bits. */ 00158 fid_UINTSIZE_64 /*!<\brief Integer size is 64 bits. */ 00159 } fid_Uintsize; 00160 00161 /*! 00162 * \brief A type that represents either 32 or 64 bit unsigned integer. 00163 * 00164 * \see fid_Uintsize, fid_SWITCH48(), fid_VALUE48(), fid_PRINT48(). 00165 */ 00166 typedef union 00167 { 00168 fid_Uint32 v_uint32; /*!< 32 bit unsigned integer. */ 00169 fid_Uint64 v_uint64; /*!< 64 bit unsigned integer. */ 00170 00171 #ifdef __cplusplus 00172 fid_Uint32 operator=(const fid_Uint32 &v) { return v_uint32=v; } 00173 fid_Uint64 operator=(const fid_Uint64 &v) { return v_uint64=v; } 00174 fid_Uint32 operator-=(const fid_Uint32 &v) { return v_uint32-=v; } 00175 fid_Uint64 operator-=(const fid_Uint64 &v) { return v_uint64-=v; } 00176 fid_Uint32 operator+=(const fid_Uint32 &v) { return v_uint32+=v; } 00177 fid_Uint64 operator+=(const fid_Uint64 &v) { return v_uint64+=v; } 00178 00179 bool operator==(const fid_Uint32 &v) const { return v_uint32 == v; } 00180 bool operator==(const fid_Uint64 &v) const { return v_uint64 == v; } 00181 bool operator<(const fid_Uint32 &v) const { return v_uint32 < v; } 00182 bool operator<(const fid_Uint64 &v) const { return v_uint64 < v; } 00183 bool operator<=(const fid_Uint32 &v) const { return v_uint32 <= v; } 00184 bool operator<=(const fid_Uint64 &v) const { return v_uint64 <= v; } 00185 bool operator>(const fid_Uint32 &v) const { return v_uint32 > v; } 00186 bool operator>(const fid_Uint64 &v) const { return v_uint64 > v; } 00187 bool operator>=(const fid_Uint32 &v) const { return v_uint32 >= v; } 00188 bool operator>=(const fid_Uint64 &v) const { return v_uint64 >= v; } 00189 #endif /* __cplusplus */ 00190 } fid_Uint48; 00191 00192 /*! 00193 * \brief A type that represents const pointers to either 32 or 64 bit 00194 * unsigned integers. 00195 * 00196 * \see fid_Uint48. 00197 */ 00198 typedef union 00199 { 00200 const fid_Uint32 *v_uint32; /*!< Pointer to 32 bit unsigned integer. */ 00201 const fid_Uint64 *v_uint64; /*!< Pointer to 64 bit unsigned integer. */ 00202 } fid_Uint48constptr; 00203 00204 /*! 00205 * \brief Branch code into 32 and 64 bit versions. 00206 * 00207 * If \p UISIZE contains an invalid value, then the program will be terminated 00208 * by calling \c abort(). 00209 * 00210 * \param UISIZE A value of type #fid_Uintsize. 00211 * \param CODE32 32 bit code. 00212 * \param CODE64 64 bit code. 00213 */ 00214 #define fid_SWITCH48(UISIZE,CODE32,CODE64)\ 00215 switch(UISIZE)\ 00216 {\ 00217 case fid_UINTSIZE_32:\ 00218 CODE32\ 00219 break;\ 00220 case fid_UINTSIZE_64:\ 00221 CODE64\ 00222 break;\ 00223 default:\ 00224 abort();\ 00225 } 00226 00227 /*! 00228 * \brief Assign value to a fid_Uint48 or fid_Uint48constptr type. 00229 * 00230 * \param VAR Variable of type #fid_Uint48 or #fid_Uint48constptr. 00231 * \param UISIZE A value of type #fid_Uintsize. 00232 * \param VAL An integer value. No type cast is performed. 00233 */ 00234 #define fid_ASSIGN48(VAR,UISIZE,VAL)\ 00235 fid_SWITCH48(UISIZE,(VAR).v_uint32=(VAL);,(VAR).v_uint64=(VAL);) 00236 00237 /*! 00238 * \brief Fetch value from a fid_Uint48 or fid_Uint48constptr type. 00239 * 00240 * \param UISIZE A value of type #fid_Uintsize. 00241 * \param VAL A value of type fid_Uint48. 00242 * 00243 * \returns Either a fid_Uint32 or a #fid_Uint64 value, as stored in \p VAL. 00244 * 00245 * \note This macro does not abort if \p UISIZE contains an invalid value. 00246 */ 00247 #define fid_VALUE48(UISIZE,VAL)\ 00248 ((UISIZE) == fid_UINTSIZE_32?(VAL).v_uint32:(VAL).v_uint64) 00249 00250 /*! 00251 * \brief Fetch value from a fid_Uint48 type for printing. 00252 * 00253 * Use the fid_U64FMT format string to print values returned by this macro. 00254 * 00255 * \param UISIZE A value of type #fid_Uintsize. 00256 * \param VAL A value of type fid_Uint48. 00257 * 00258 * \returns The value stored in \p VAL as #fid_Uint64 value. 00259 * 00260 * \note This macro does not abort if \p UISIZE contains an invalid value. 00261 */ 00262 #define fid_PRINT48(UISIZE,VAL)\ 00263 ((UISIZE) == fid_UINTSIZE_32\ 00264 ?(fid_Uint64)(VAL).v_uint32\ 00265 :(VAL).v_uint64) 00266 00267 /*@}*/ 00268 #endif /* !LIBFIDINTTYPES_H */