libStatGen Software  1
Generic.h
1 /*
2  * Copyright (C) 2010 Regents of the University of Michigan
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #if !defined(_GENERIC_H)
19 #define _GENERIC_H
20 
21 #include <stdint.h>
22 
23 #include <list>
24 #include <iostream>
25 #include <ostream>
26 #include <utility>
27 #include <vector>
28 #include <string>
29 
30 template <typename T>
31 inline T abs(T x)
32 {
33  return (x < 0) ? -x : x;
34 }
35 
36 //
37 // this is safe for signed/unsigned:
38 //
39 template <typename T>
40 inline T absDiff(T x, T y)
41 {
42  return (x < y) ? (y - x) : (x - y);
43 }
44 
45 //
46 //
47 template <typename T>
48 inline T in(T x, T y, T z)
49 {
50  return (x >= y && x < z);
51 }
52 
53 //
54 // These overloaded operators and functions are largely
55 // for diagnostic debug printing. The underlying problem
56 // is that gdb is unable to decipher any STL use, let alone
57 // complex STL use. printf debugging is a poor second choice,
58 // but these functions at least make it practical to do rapidly.
59 //
60 
61 //
62 // Write a std::pair to a stream
63 //
64 template <typename A, typename B>
65 std::ostream &operator << (std::ostream &stream, std::pair<A, B> p)
66 {
67  stream << "(" << p.first << ", " << p.second << ")";
68  return stream;
69 }
70 
71 //
72 // generic vector print -- in normal use, you should
73 // be able to simply do foostream << somevector, and get
74 // sane results, provided that the vector elements themselves
75 // can be written to the stream.
76 //
77 // Example code is in Generic.cpp
78 //
79 template <typename T>
80 std::ostream &operator << (std::ostream &stream, std::vector<T> const &v)
81 {
82 
83  typename std::vector<T>::const_iterator i;
84  for (i = v.begin(); i != v.end(); i++)
85  {
86  stream << (i - v.begin()) << ": " << *i << std::endl;
87  }
88  return stream;
89 }
90 
91 //
92 // same overload as above, except for std::list
93 //
94 template <typename T>
95 std::ostream &operator << (std::ostream &stream, std::list<T> const &l)
96 {
97 
98  typename std::list<T>::const_iterator i;
99  int j = 0;
100  for (i = l.begin(); i != l.end(); i++, j++)
101  {
102  stream << j << ": " << *i << std::endl;
103  }
104  return stream;
105 }
106 
107 template <typename TITLE, typename ITEM, typename EXPECT, typename GOT>
108 void check(int &returnCode, TITLE title, ITEM item, EXPECT expect, GOT got)
109 {
110  if (expect!=got)
111  {
112  std::cout << "Test " << title << ": expect " << item << " = '" << expect << "', but got '" << got << "'." << std::endl;
113  returnCode += 1;
114  }
115 }
116 
117 //
118 // specialization of template below:
119 // load a set of lines from a file into a vector of strings.
120 //
121 inline std::istream &operator >> (std::istream &stream, std::vector<std::string> &vec)
122 {
123  std::string val;
124  while (true)
125  {
126  if (!stream.good()) break;
127  getline(stream, val);
128  stream >> val;
129  vec.push_back(val);
130  }
131  return stream;
132 }
133 
134 
135 //
136 // read values from a stream, appending to the provided
137 // vec. stops when the stream is consumed.
138 //
139 template<typename T>
140 std::istream &operator >> (std::istream &stream, std::vector<T> &vec)
141 {
142  T val;
143  while (true)
144  {
145  if (!stream.good()) break;
146  stream >> val;
147  vec.push_back(val);
148  }
149  return stream;
150 }
151 
152 
153 #if 0
154 //
155 // generic vector of iterators print
156 //
157 template <typename T>
158 std::ostream &operator << (
159  std::ostream &stream,
160  std::vector<
161  std::pair< std::vector<typename T>::iterator , std::vector< typename T>::iterator >
162  > v
163 )
164 {
165 
166  typename IteratorType i;
167  typename std::vector<T>::iterator i;
168  for (i = v.begin(); i != v.end(); i++)
169  {
170  stream << *i << std::endl;
171  }
172  return stream;
173 }
174 
175 #endif
176 
177 
178 //
179 // These are packed set/get functions for dealing with
180 // packed 1, 2 and 4 bit unsigned values inside of arbitrary
181 // arrays of data (char */std::vector<char> whatever).
182 //
183 template<typename T>
184 inline uint32_t PackedAccess_1Bit(T byteSequence, uint32_t bitIndex)
185 {
186  return (((byteSequence)[bitIndex>>3] >> (bitIndex&0x7)) & 0x1);
187 }
188 
189 template<typename T>
190 inline void PackedAssign_1Bit(T byteSequence, uint32_t bitIndex, uint32_t value)
191 {
192  (byteSequence)[bitIndex>>3] =
193  ((byteSequence)[bitIndex>>3]
194  & ~(1<<(bitIndex&0x07)))
195  | ((value&0x01)<<(bitIndex&0x7));
196 }
197 
198 inline size_t Packed1BitElementCount2Bytes(uint32_t i)
199 {
200  return (size_t)(i+7)/8;
201 }
202 
203 template<typename T>
204 inline uint32_t PackedAccess_2Bit(T byteSequence, uint32_t index)
205 {
206  return (((byteSequence)[index>>2] >> ((index&0x3)<<1)) & 0x3);
207 }
208 
209 template<typename T>
210 inline void PackedAssign_2Bit(T byteSequence, uint32_t index, uint32_t value)
211 {
212  (byteSequence)[index>>2] =
213  ((byteSequence)[index>>2]
214  & ~(3<<((index&0x03)<<1)))
215  | ((value&0x03)<<((index&0x3)<<1));
216 }
217 
218 inline size_t Packed2BitElementCount2Bytes(uint32_t i)
219 {
220  return (size_t)(i+3)/4;
221 }
222 
223 template<typename T>
224 inline uint32_t PackedAccess_4Bit(T byteSequence, uint32_t index)
225 {
226  return (((byteSequence)[index>>1] >> ((index&0x1)<<2)) & 0xf);
227 }
228 
229 template<typename T>
230 inline void PackedAssign_4Bit(T byteSequence, uint32_t index, uint32_t value)
231 {
232  (byteSequence)[index>>1] =
233  ((byteSequence)[index>>1]
234  & ~(7<<((index&0x01)<<2)))
235  | ((value&0x0f)<<((index&0x1)<<2));
236 }
237 
238 inline size_t Packed4BitElementCount2Bytes(uint32_t i)
239 {
240  return (size_t)(i+1)/2;
241 }
242 
243 #endif
IFILE operator>>(IFILE stream, std::string &str)
Read a line from a file using streaming.
Definition: InputFile.h:724
InputFile & operator<<(InputFile &stream, const std::string &str)
Write to a file using streaming.
Definition: InputFile.h:736