libStatGen Software
1
|
00001 /* 00002 * Copyright (C) 2010 Regents of the University of Michigan 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #if !defined(_GENERIC_H) 00019 #define _GENERIC_H 00020 00021 #include <stdint.h> 00022 00023 #include <list> 00024 #include <iostream> 00025 #include <ostream> 00026 #include <utility> 00027 #include <vector> 00028 #include <string> 00029 00030 template <typename T> 00031 inline T abs(T x) 00032 { 00033 return (x < 0) ? -x : x; 00034 } 00035 00036 // 00037 // this is safe for signed/unsigned: 00038 // 00039 template <typename T> 00040 inline T absDiff(T x, T y) 00041 { 00042 return (x < y) ? (y - x) : (x - y); 00043 } 00044 00045 // 00046 // 00047 template <typename T> 00048 inline T in(T x, T y, T z) 00049 { 00050 return (x >= y && x < z); 00051 } 00052 00053 // 00054 // These overloaded operators and functions are largely 00055 // for diagnostic debug printing. The underlying problem 00056 // is that gdb is unable to decipher any STL use, let alone 00057 // complex STL use. printf debugging is a poor second choice, 00058 // but these functions at least make it practical to do rapidly. 00059 // 00060 00061 // 00062 // Write a std::pair to a stream 00063 // 00064 template <typename A, typename B> 00065 std::ostream &operator << (std::ostream &stream, std::pair<A, B> p) 00066 { 00067 stream << "(" << p.first << ", " << p.second << ")"; 00068 return stream; 00069 } 00070 00071 // 00072 // generic vector print -- in normal use, you should 00073 // be able to simply do foostream << somevector, and get 00074 // sane results, provided that the vector elements themselves 00075 // can be written to the stream. 00076 // 00077 // Example code is in Generic.cpp 00078 // 00079 template <typename T> 00080 std::ostream &operator << (std::ostream &stream, std::vector<T> const &v) 00081 { 00082 00083 typename std::vector<T>::const_iterator i; 00084 for (i = v.begin(); i != v.end(); i++) 00085 { 00086 stream << (i - v.begin()) << ": " << *i << std::endl; 00087 } 00088 return stream; 00089 } 00090 00091 // 00092 // same overload as above, except for std::list 00093 // 00094 template <typename T> 00095 std::ostream &operator << (std::ostream &stream, std::list<T> const &l) 00096 { 00097 00098 typename std::list<T>::const_iterator i; 00099 int j = 0; 00100 for (i = l.begin(); i != l.end(); i++, j++) 00101 { 00102 stream << j << ": " << *i << std::endl; 00103 } 00104 return stream; 00105 } 00106 00107 template <typename TITLE, typename ITEM, typename EXPECT, typename GOT> 00108 void check(int &returnCode, TITLE title, ITEM item, EXPECT expect, GOT got) 00109 { 00110 if (expect!=got) 00111 { 00112 std::cout << "Test " << title << ": expect " << item << " = '" << expect << "', but got '" << got << "'." << std::endl; 00113 returnCode += 1; 00114 } 00115 } 00116 00117 // 00118 // specialization of template below: 00119 // load a set of lines from a file into a vector of strings. 00120 // 00121 inline std::istream &operator >> (std::istream &stream, std::vector<std::string> &vec) 00122 { 00123 std::string val; 00124 while (true) 00125 { 00126 if (!stream.good()) break; 00127 getline(stream, val); 00128 stream >> val; 00129 vec.push_back(val); 00130 } 00131 return stream; 00132 } 00133 00134 00135 // 00136 // read values from a stream, appending to the provided 00137 // vec. stops when the stream is consumed. 00138 // 00139 template<typename T> 00140 std::istream &operator >> (std::istream &stream, std::vector<T> &vec) 00141 { 00142 T val; 00143 while (true) 00144 { 00145 if (!stream.good()) break; 00146 stream >> val; 00147 vec.push_back(val); 00148 } 00149 return stream; 00150 } 00151 00152 00153 #if 0 00154 // 00155 // generic vector of iterators print 00156 // 00157 template <typename T> 00158 std::ostream &operator << ( 00159 std::ostream &stream, 00160 std::vector< 00161 std::pair< std::vector<typename T>::iterator , std::vector< typename T>::iterator > 00162 > v 00163 ) 00164 { 00165 00166 typename IteratorType i; 00167 typename std::vector<T>::iterator i; 00168 for (i = v.begin(); i != v.end(); i++) 00169 { 00170 stream << *i << std::endl; 00171 } 00172 return stream; 00173 } 00174 00175 #endif 00176 00177 00178 // 00179 // These are packed set/get functions for dealing with 00180 // packed 1, 2 and 4 bit unsigned values inside of arbitrary 00181 // arrays of data (char */std::vector<char> whatever). 00182 // 00183 template<typename T> 00184 inline uint32_t PackedAccess_1Bit(T byteSequence, uint32_t bitIndex) 00185 { 00186 return (((byteSequence)[bitIndex>>3] >> (bitIndex&0x7)) & 0x1); 00187 } 00188 00189 template<typename T> 00190 inline void PackedAssign_1Bit(T byteSequence, uint32_t bitIndex, uint32_t value) 00191 { 00192 (byteSequence)[bitIndex>>3] = 00193 ((byteSequence)[bitIndex>>3] 00194 & ~(1<<(bitIndex&0x07))) 00195 | ((value&0x01)<<(bitIndex&0x7)); 00196 } 00197 00198 inline size_t Packed1BitElementCount2Bytes(uint32_t i) 00199 { 00200 return (size_t)(i+7)/8; 00201 } 00202 00203 template<typename T> 00204 inline uint32_t PackedAccess_2Bit(T byteSequence, uint32_t index) 00205 { 00206 return (((byteSequence)[index>>2] >> ((index&0x3)<<1)) & 0x3); 00207 } 00208 00209 template<typename T> 00210 inline void PackedAssign_2Bit(T byteSequence, uint32_t index, uint32_t value) 00211 { 00212 (byteSequence)[index>>2] = 00213 ((byteSequence)[index>>2] 00214 & ~(3<<((index&0x03)<<1))) 00215 | ((value&0x03)<<((index&0x3)<<1)); 00216 } 00217 00218 inline size_t Packed2BitElementCount2Bytes(uint32_t i) 00219 { 00220 return (size_t)(i+3)/4; 00221 } 00222 00223 template<typename T> 00224 inline uint32_t PackedAccess_4Bit(T byteSequence, uint32_t index) 00225 { 00226 return (((byteSequence)[index>>1] >> ((index&0x1)<<2)) & 0xf); 00227 } 00228 00229 template<typename T> 00230 inline void PackedAssign_4Bit(T byteSequence, uint32_t index, uint32_t value) 00231 { 00232 (byteSequence)[index>>1] = 00233 ((byteSequence)[index>>1] 00234 & ~(7<<((index&0x01)<<2))) 00235 | ((value&0x0f)<<((index&0x1)<<2)); 00236 } 00237 00238 inline size_t Packed4BitElementCount2Bytes(uint32_t i) 00239 { 00240 return (size_t)(i+1)/2; 00241 } 00242 00243 #endif