libStatGen Software  1
Generic.h
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends