libStatGen Software 1
Loading...
Searching...
No Matches
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
30template <typename T>
31inline T abs(T x)
32{
33 return (x < 0) ? -x : x;
34}
35
36//
37// this is safe for signed/unsigned:
38//
39template <typename T>
40inline T absDiff(T x, T y)
41{
42 return (x < y) ? (y - x) : (x - y);
43}
44
45//
46//
47template <typename T>
48inline 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//
64template <typename A, typename B>
65std::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//
79template <typename T>
80std::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//
94template <typename T>
95std::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
107template <typename TITLE, typename ITEM, typename EXPECT, typename GOT>
108void 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//
121inline 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//
139template<typename T>
140std::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//
157template <typename T>
158std::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//
183template<typename T>
184inline uint32_t PackedAccess_1Bit(T byteSequence, uint32_t bitIndex)
185{
186 return (((byteSequence)[bitIndex>>3] >> (bitIndex&0x7)) & 0x1);
187}
188
189template<typename T>
190inline 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
198inline size_t Packed1BitElementCount2Bytes(uint32_t i)
199{
200 return (size_t)(i+7)/8;
201}
202
203template<typename T>
204inline uint32_t PackedAccess_2Bit(T byteSequence, uint32_t index)
205{
206 return (((byteSequence)[index>>2] >> ((index&0x3)<<1)) & 0x3);
207}
208
209template<typename T>
210inline 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
218inline size_t Packed2BitElementCount2Bytes(uint32_t i)
219{
220 return (size_t)(i+3)/4;
221}
222
223template<typename T>
224inline uint32_t PackedAccess_4Bit(T byteSequence, uint32_t index)
225{
226 return (((byteSequence)[index>>1] >> ((index&0x1)<<2)) & 0xf);
227}
228
229template<typename T>
230inline 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
238inline size_t Packed4BitElementCount2Bytes(uint32_t i)
239{
240 return (size_t)(i+1)/2;
241}
242
243#endif