μHAL (v2.6.5)
Part of the IPbus software repository
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 <stdint.h> // for uint32_t, uint8_t, uint16_t, int32_t, ...
35 #include <ostream> // for ostream, basic_ostream::put
36 #include "uhal/log/log_inserter_helper.hpp" // for RefWrapper
37 
38 
39 namespace uhal
40 {
41 
42 
43  template< typename T >
44  _Integer< T , IntFmt<> > Integer ( const T& aT )
45  {
46  return _Integer< T , IntFmt<> > ( aT );
47  }
48 
49  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>& aFmt )
50  {
52  }
53 
54 
55  template< typename T >
56  void sign_helper ( std::ostream& aStr, const T& aInt ) {}
57 
58 
59 
60 
61 
62  template< typename T , uint32_t WIDTH >
63  void _Integer< T , IntFmt<bin , fixed , WIDTH> >::print ( std::ostream& aStr ) const
64  {
65  uint32_t lSize ( sizeof ( T ) << 3 ); //number of characters
66  aStr.write ( "0b" , 2 );
67  int32_t i ( WIDTH-lSize );
68 
69  if ( i > 0 )
70  {
71  for ( ; i!=0 ; --i )
72  {
73  aStr.put ( '0' );
74  }
75  }
76 
77  T lValue ( RefWrapper<T>::value() );
78  T lMask ( 0x1 );
79  lMask <<= ( lSize-1 );
80 
81  for ( uint32_t i=0 ; i!=lSize ; ++i )
82  {
83  aStr.put ( ( lValue & lMask ) ?'1':'0' );
84  lValue <<= 1;
85  }
86  }
87 
88 
89  template< typename T , uint32_t WIDTH >
90  void _Integer< T , IntFmt<dec , fixed , WIDTH> >::print ( std::ostream& aStr ) const
91  {
92  static const char* lCharacterMapping ( "9876543210123456789" );
93  static const char* lCharacterMappingCenter ( lCharacterMapping + 9 );
94  char lBuffer[24]; //greater than the size of a 64bit decimal number
95  char* lPtr = lBuffer;
96  T value ( RefWrapper<T>::value() );
97  T tmp_value;
98  sign_helper ( aStr , value );
99 
100  do
101  {
102  tmp_value = value;
103  value /= 10;
104  *lPtr++ = * ( lCharacterMappingCenter + tmp_value - ( value * 10 ) );
105  }
106  while ( value );
107 
108  int32_t i ( WIDTH- ( lPtr-lBuffer ) );
109 
110  if ( i > 0 )
111  {
112  for ( ; i!=0 ; --i )
113  {
114  aStr.put ( '0' );
115  }
116  }
117 
118  do
119  {
120  aStr.put ( * ( --lPtr ) );
121  }
122  while ( lPtr!=lBuffer );
123  }
124 
125 
126  template< typename T , uint32_t WIDTH >
127  void _Integer< T , IntFmt<hex , fixed , WIDTH> >::print ( std::ostream& aStr ) const
128  {
129  uint32_t lSize ( sizeof ( T ) << 1 ); //number of characters
130  static const char* lCharacterMapping ( "0123456789ABCDEF" );
131  aStr.write ( "0x" , 2 );
132  int32_t i ( WIDTH-lSize );
133 
134  if ( i > 0 )
135  {
136  for ( ; i!=0 ; --i )
137  {
138  aStr.put ( '0' );
139  }
140  }
141 
142  uint8_t* lStart ( ( uint8_t* ) ( & RefWrapper<T>::value() ) );
143  uint8_t* lPtr ( lStart + sizeof ( T ) );
144 
145  do
146  {
147  --lPtr;
148  aStr.put ( * ( lCharacterMapping + ( ( ( *lPtr ) &0xF0 ) >>4 ) ) );
149  aStr.put ( * ( lCharacterMapping + ( ( ( *lPtr ) &0x0F ) ) ) );
150  }
151  while ( lPtr!=lStart );
152  }
153 
154 
155 
156 
157  template< typename T , uint32_t WIDTH >
158  void _Integer< T , IntFmt<bin , variable , WIDTH> >::print ( std::ostream& aStr ) const
159  {
160  if ( RefWrapper<T>::value() == T ( 0 ) )
161  {
162  aStr.write ( "0b0" , 3 );
163  }
164  else
165  {
166  uint32_t lSize ( sizeof ( T ) <<3 );
167  aStr.write ( "0b" , 2 );
168  T lValue ( RefWrapper<T>::value() );
169  T lMask ( 0x1 );
170  lMask <<= ( lSize-1 );
171  bool lPrint ( false );
172  bool lCurrent ( false );
173 
174  for ( uint32_t i=0 ; i!=lSize ; ++i )
175  {
176  lCurrent = lValue & lMask;
177 
178  if ( (lPrint |= lCurrent) )
179  {
180  aStr.put ( lCurrent?'1':'0' );
181  }
182 
183  lValue <<= 1;
184  }
185  }
186  }
187 
188 
189 
190  template< typename T , uint32_t WIDTH >
191  void _Integer< T , IntFmt<dec , variable , WIDTH> >::print ( std::ostream& aStr ) const
192  {
193  static const char* lCharacterMapping ( "9876543210123456789" );
194  static const char* lCharacterMappingCenter ( lCharacterMapping + 9 );
195  char lBuffer[24]; //greater than the size of a 64bit decimal number
196  char* lPtr = lBuffer;
197  T value ( RefWrapper<T>::value() );
198  T tmp_value;
199  sign_helper ( aStr , value );
200 
201  do
202  {
203  tmp_value = value;
204  value /= 10;
205  *lPtr++ = * ( lCharacterMappingCenter + tmp_value - ( value * 10 ) );
206  }
207  while ( value );
208 
209  do
210  {
211  aStr.put ( * ( --lPtr ) );
212  }
213  while ( lPtr!=lBuffer );
214  }
215 
216 
217 
218  template< typename T , uint32_t WIDTH >
219  void _Integer< T , IntFmt<hex , variable , WIDTH> >::print ( std::ostream& aStr ) const
220  {
221  static const char* lCharacterMapping ( "0123456789ABCDEF" );
222 
223  if ( RefWrapper<T>::value() == T ( 0 ) )
224  {
225  aStr.write ( "0x0" , 3 );
226  }
227  else
228  {
229  uint32_t lSize ( sizeof ( T ) );
230  aStr.write ( "0x" , 2 );
231  bool lPrint ( false );
232  uint32_t lPos ( 0 );
233  uint8_t* lStart ( ( uint8_t* ) ( & RefWrapper<T>::value() ) );
234  uint8_t* lPtr ( lStart + lSize );
235 
236  do
237  {
238  --lPtr;
239  lPos = ( ( ( *lPtr ) &0xF0 ) >>4 );
240 
241  if ( (lPrint |= ( bool ) ( lPos )) )
242  {
243  aStr.put ( * ( lCharacterMapping + lPos ) );
244  }
245 
246  lPos = ( ( *lPtr ) &0x0F );
247 
248  if ( (lPrint |= ( bool ) ( lPos )) )
249  {
250  aStr.put ( * ( lCharacterMapping + lPos ) );
251  }
252  }
253  while ( lPtr!=lStart );
254  }
255  }
256 
257 
258 
259  template< typename FORMAT >
260  std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< uint8_t , FORMAT >& aInt )
261  {
262  aInt.print ( aStr );
263  return aStr;
264  }
265 
266  template< typename FORMAT >
267  std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< int8_t , FORMAT >& aInt )
268  {
269  aInt.print ( aStr );
270  return aStr;
271  }
272 
273  template< typename FORMAT >
274  std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< uint16_t , FORMAT >& aInt )
275  {
276  aInt.print ( aStr );
277  return aStr;
278  }
279 
280  template< typename FORMAT >
281  std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< int16_t , FORMAT >& aInt )
282  {
283  aInt.print ( aStr );
284  return aStr;
285  }
286 
287  template< typename FORMAT >
288  std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< uint32_t , FORMAT >& aInt )
289  {
290  aInt.print ( aStr );
291  return aStr;
292  }
293 
294  template< typename FORMAT >
295  std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< int32_t , FORMAT >& aInt )
296  {
297  aInt.print ( aStr );
298  return aStr;
299  }
300 
301  template< typename FORMAT >
302  std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< uint64_t , FORMAT >& aInt )
303  {
304  aInt.print ( aStr );
305  return aStr;
306  }
307 
308  template< typename FORMAT >
309  std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< int64_t , FORMAT >& aInt )
310  {
311  aInt.print ( aStr );
312  return aStr;
313  }
314 
315 #ifdef __APPLE__
316  template< typename FORMAT >
317  std::ostream& operator<< ( std::ostream& aStr , const uhal::_Integer< size_t , FORMAT >& aInt )
318  {
319  aInt.print ( aStr );
320  return aStr;
321  }
322 #endif
323 
324 }
Forward declare an ultra-lightweight wrapper which does formatting of numbers only on demand...
Empty struct which acts as a dummy variable for passing the formatting information around...
void print(std::ostream &aStr, const tm *aTm, const uint32_t &aUsec)
Format a time element for for sending to the log.
void sign_helper(std::ostream &aStr, const T &aInt)
Helper function for adding the &#39;+&#39;/&#39;-&#39; sign.
_Integer< T, IntFmt<> > Integer(const T &aT)
Forward declare a function which creates an instance of the ultra-lightweight wrapper from an integer...