μHAL (v2.8.17)
Part of the IPbus software repository
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
log_inserters.integer.hxx
Go to the documentation of this file.
1/*
2---------------------------------------------------------------------------
3
4 This file is part of uHAL.
5
6 uHAL is a hardware access library and programming framework
7 originally developed for upgrades of the Level-1 trigger of the CMS
8 experiment at CERN.
9
10 uHAL is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 uHAL is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with uHAL. If not, see <http://www.gnu.org/licenses/>.
22
23
24 Andrew Rose, Imperial College, London
25 email: awr01 <AT> imperial.ac.uk
26
27 Marc Magrans de Abril, CERN
28 email: marc.magrans.de.abril <AT> cern.ch
29
30---------------------------------------------------------------------------
31*/
32
33
34#include <ostream> // for ostream, basic_ostream::put
35#include <stdint.h> // for uint32_t, uint8_t, uint16_t, int32_t, ...
36
37#include "uhal/log/log_inserter_helper.hpp" // for RefWrapper
38
39
40namespace uhal
41{
42 template< typename T >
44 {
45 return _Integer< T , IntFmt<> > ( aT );
46 }
47
48 template< typename T , integer_base BASE , integer_format FORMAT , uint32_t WIDTH > _Integer< T , IntFmt<BASE , FORMAT , WIDTH> > Integer ( const T& aT , const IntFmt<BASE , FORMAT , WIDTH>& )
49 {
51 }
52
53
54 template< typename T >
55 void sign_helper ( std::ostream&, const T& ) {}
56
57
58
59 template< typename T , uint32_t WIDTH >
60 void _Integer< T , IntFmt<bin , fixed , WIDTH> >::print ( std::ostream& aStr ) const
61 {
62 uint32_t lSize ( sizeof ( T ) << 3 ); //number of characters
63 aStr.write ( "0b" , 2 );
64 int32_t i ( WIDTH-lSize );
65
66 if ( i > 0 )
67 {
68 for ( ; i!=0 ; --i )
69 {
70 aStr.put ( '0' );
71 }
72 }
73
74 T lValue ( RefWrapper<T>::value() );
75 T lMask ( 0x1 );
76 lMask <<= ( lSize-1 );
77
78 for ( uint32_t i=0 ; i!=lSize ; ++i )
79 {
80 aStr.put ( ( lValue & lMask ) ?'1':'0' );
81 lValue <<= 1;
82 }
83 }
84
85
86 template< typename T , uint32_t WIDTH >
87 void _Integer< T , IntFmt<dec , fixed , WIDTH> >::print ( std::ostream& aStr ) const
88 {
89 static const char* lCharacterMapping ( "9876543210123456789" );
90 static const char* lCharacterMappingCenter ( lCharacterMapping + 9 );
91 char lBuffer[24]; //greater than the size of a 64bit decimal number
92 char* lPtr = lBuffer;
93 T value ( RefWrapper<T>::value() );
94 T tmp_value;
95 sign_helper ( aStr , value );
96
97 do
98 {
99 tmp_value = value;
100 value /= 10;
101 *lPtr++ = * ( lCharacterMappingCenter + tmp_value - ( value * 10 ) );
102 }
103 while ( value );
104
105 int32_t i ( WIDTH- ( lPtr-lBuffer ) );
106
107 if ( i > 0 )
108 {
109 for ( ; i!=0 ; --i )
110 {
111 aStr.put ( '0' );
112 }
113 }
114
115 do
116 {
117 aStr.put ( * ( --lPtr ) );
118 }
119 while ( lPtr!=lBuffer );
120 }
121
122
123 template< typename T , uint32_t WIDTH >
124 void _Integer< T , IntFmt<hex , fixed , WIDTH> >::print ( std::ostream& aStr ) const
125 {
126 uint32_t lSize ( sizeof ( T ) << 1 ); //number of characters
127 static const char* lCharacterMapping ( "0123456789ABCDEF" );
128 aStr.write ( "0x" , 2 );
129 int32_t i ( WIDTH-lSize );
130
131 if ( i > 0 )
132 {
133 for ( ; i!=0 ; --i )
134 {
135 aStr.put ( '0' );
136 }
137 }
138
139 uint8_t* lStart ( ( uint8_t* ) ( & RefWrapper<T>::value() ) );
140 uint8_t* lPtr ( lStart + sizeof ( T ) );
141
142 do
143 {
144 --lPtr;
145 aStr.put ( * ( lCharacterMapping + ( ( ( *lPtr ) &0xF0 ) >>4 ) ) );
146 aStr.put ( * ( lCharacterMapping + ( ( ( *lPtr ) &0x0F ) ) ) );
147 }
148 while ( lPtr!=lStart );
149 }
150
151
152
153
154 template< typename T , uint32_t WIDTH >
155 void _Integer< T , IntFmt<bin , variable , WIDTH> >::print ( std::ostream& aStr ) const
156 {
157 if ( RefWrapper<T>::value() == T ( 0 ) )
158 {
159 aStr.write ( "0b0" , 3 );
160 }
161 else
162 {
163 uint32_t lSize ( sizeof ( T ) <<3 );
164 aStr.write ( "0b" , 2 );
165 T lValue ( RefWrapper<T>::value() );
166 T lMask ( 0x1 );
167 lMask <<= ( lSize-1 );
168 bool lPrint ( false );
169 bool lCurrent ( false );
170
171 for ( uint32_t i=0 ; i!=lSize ; ++i )
172 {
173 lCurrent = lValue & lMask;
174
175 if ( (lPrint |= lCurrent) )
176 {
177 aStr.put ( lCurrent?'1':'0' );
178 }
179
180 lValue <<= 1;
181 }
182 }
183 }
184
185
186
187 template< typename T , uint32_t WIDTH >
188 void _Integer< T , IntFmt<dec , variable , WIDTH> >::print ( std::ostream& aStr ) const
189 {
190 static const char* lCharacterMapping ( "9876543210123456789" );
191 static const char* lCharacterMappingCenter ( lCharacterMapping + 9 );
192 char lBuffer[24]; //greater than the size of a 64bit decimal number
193 char* lPtr = lBuffer;
194 T value ( RefWrapper<T>::value() );
195 T tmp_value;
196 sign_helper ( aStr , value );
197
198 do
199 {
200 tmp_value = value;
201 value /= 10;
202 *lPtr++ = * ( lCharacterMappingCenter + tmp_value - ( value * 10 ) );
203 }
204 while ( value );
205
206 do
207 {
208 aStr.put ( * ( --lPtr ) );
209 }
210 while ( lPtr!=lBuffer );
211 }
212
213
214
215 template< typename T , uint32_t WIDTH >
216 void _Integer< T , IntFmt<hex , variable , WIDTH> >::print ( std::ostream& aStr ) const
217 {
218 static const char* lCharacterMapping ( "0123456789ABCDEF" );
219
220 if ( RefWrapper<T>::value() == T ( 0 ) )
221 {
222 aStr.write ( "0x0" , 3 );
223 }
224 else
225 {
226 uint32_t lSize ( sizeof ( T ) );
227 aStr.write ( "0x" , 2 );
228 bool lPrint ( false );
229 uint32_t lPos ( 0 );
230 uint8_t* lStart ( ( uint8_t* ) ( & RefWrapper<T>::value() ) );
231 uint8_t* lPtr ( lStart + lSize );
232
233 do
234 {
235 --lPtr;
236 lPos = ( ( ( *lPtr ) &0xF0 ) >>4 );
237
238 if ( (lPrint |= ( bool ) ( lPos )) )
239 {
240 aStr.put ( * ( lCharacterMapping + lPos ) );
241 }
242
243 lPos = ( ( *lPtr ) &0x0F );
244
245 if ( (lPrint |= ( bool ) ( lPos )) )
246 {
247 aStr.put ( * ( lCharacterMapping + lPos ) );
248 }
249 }
250 while ( lPtr!=lStart );
251 }
252 }
253
254
255
256 template< typename FORMAT >
257 std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< uint8_t , FORMAT >& aInt )
258 {
259 aInt.print ( aStr );
260 return aStr;
261 }
262
263 template< typename FORMAT >
264 std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< int8_t , FORMAT >& aInt )
265 {
266 aInt.print ( aStr );
267 return aStr;
268 }
269
270 template< typename FORMAT >
271 std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< uint16_t , FORMAT >& aInt )
272 {
273 aInt.print ( aStr );
274 return aStr;
275 }
276
277 template< typename FORMAT >
278 std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< int16_t , FORMAT >& aInt )
279 {
280 aInt.print ( aStr );
281 return aStr;
282 }
283
284 template< typename FORMAT >
285 std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< uint32_t , FORMAT >& aInt )
286 {
287 aInt.print ( aStr );
288 return aStr;
289 }
290
291 template< typename FORMAT >
292 std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< int32_t , FORMAT >& aInt )
293 {
294 aInt.print ( aStr );
295 return aStr;
296 }
297
298 template< typename FORMAT >
299 std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< uint64_t , FORMAT >& aInt )
300 {
301 aInt.print ( aStr );
302 return aStr;
303 }
304
305 template< typename FORMAT >
306 std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< int64_t , FORMAT >& aInt )
307 {
308 aInt.print ( aStr );
309 return aStr;
310 }
311
312#if __SIZEOF_LONG__ == 4
313 template< typename FORMAT >
314 std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< long int , FORMAT >& aInt )
315 {
316 aInt.print ( aStr );
317 return aStr;
318 }
319#endif
320
321#ifdef __APPLE__
322 template< typename FORMAT >
323 std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< size_t , FORMAT >& aInt )
324 {
325 aInt.print ( aStr );
326 return aStr;
327 }
328#endif
329
330}
Forward declare an ultra-lightweight wrapper which does formatting of numbers only on demand.
void print(std::ostream &aStr) const
The function which formats the integer and appends it into the given stream.
_Integer< T, IntFmt<> > Integer(const T &aT)
Forward declare a function which creates an instance of the ultra-lightweight wrapper from an integer...
void sign_helper(std::ostream &aStr, const T &aInt)
Helper function for adding the '+'/'-' sign.
std::ostream & operator<<(std::ostream &aStr, const uhal::HttpResponseType &aHttpResponse)
Empty struct which acts as a dummy variable for passing the formatting information around.