μHAL (v2.7.9)
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 <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 
40 namespace uhal
41 {
42  template< typename T >
43  _Integer< T , IntFmt<> > Integer ( const T& aT )
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>& aFmt )
49  {
51  }
52 
53 
54  template< typename T >
55  void sign_helper ( std::ostream& aStr, const T& aInt ) {}
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 }
uhal::operator<<
std::ostream & operator<<(std::ostream &aStr, const uhal::HttpResponseType &aHttpResponse)
Definition: HttpResponseGrammar.cpp:41
uhal::_Integer
Forward declare an ultra-lightweight wrapper which does formatting of numbers only on demand.
Definition: log_inserters.integer.hpp:72
uhal::_Integer::print
void print(std::ostream &aStr) const
The function which formats the integer and appends it into the given stream.
uhal::print
void print(std::ostream &aStr, const tm *aTm, const uint32_t &aUsec)
Format a time element for for sending to the log.
uhal::IntFmt
Empty struct which acts as a dummy variable for passing the formatting information around.
Definition: log_inserters.integer.hpp:68
log_inserter_helper.hpp
uhal
Definition: HttpResponseGrammar.hpp:49
uhal::RefWrapper
Definition: log_inserter_helper.hpp:45
uhal::sign_helper
void sign_helper(std::ostream &aStr, const T &aInt)
Helper function for adding the '+'/'-' sign.
Definition: log_inserters.integer.hxx:55
uhal::Integer
_Integer< T, IntFmt<> > Integer(const T &aT)
Forward declare a function which creates an instance of the ultra-lightweight wrapper from an integer...
Definition: log_inserters.integer.hxx:43