All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BinaryDumpUtils.h
Go to the documentation of this file.
1 /**
2  * @file icarusalg/Utilities/BinaryDumpUtils.h
3  * @brief Functions to dump the content of binary data chunks to console
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date December 22, 2020
6  */
7 
8 #ifndef ICARUSALG_UTILITIES_BINARYDUMPUTILS_H
9 #define ICARUSALG_UTILITIES_BINARYDUMPUTILS_H
10 
11 // C/C++ standard libraries
12 #include <ostream>
13 #include <iomanip> // std::setw()
14 #include <utility> // std::move
15 #include <type_traits> // std::is_integral_v
16 #include <cstddef> // std::size_t, std::ptrdiff_t
17 
18 
19 // -----------------------------------------------------------------------------
20 namespace icarus::ns::util::details {
21 
22  // --- BEGIN -- Wrapping objects ---------------------------------------------
23  /**
24  * @name Wrapping binary objects
25  *
26  * The objects in this section are implementation details.
27  * Interface functions convert objects into these helpers, and specific
28  * output operators (`<<`) will manage their output to stream.
29  *
30  * This is a mechanism similar to C++ STL I/O manipulators with arguments.
31  */
32  /// @{
33 
34  /**
35  * @brief An object wrapping some data (copy), with a tag type.
36  * @tparam Tag a type to make a template class instance unique
37  * @tparam T type of the data wrapped
38  * @tparam Bits size of data in `T` in bits
39  *
40  * This template is used to implement other wrappers.
41  *
42  * The role of `Tag` is just to allow distinguishing template instances with
43  * the same `T` (see for example `BinObj` and `HexObj`).
44  */
45  template <typename Tag, typename T, unsigned int const Bits = (8*sizeof(T))>
46  struct BitObjHolder {
47  T const data;
48  static constexpr unsigned int bits { Bits };
49  constexpr BitObjHolder(T data): data(data) {}
50  }; // BitObjHolder<>
51 
52 
53  struct BinObjTag {}; ///< Tag object for `BinObj`.
54 
55  /// Holder for data to be presented in binary format (base 2).
56  template <typename T, unsigned int const Bits = (8*sizeof(T))>
57  struct BinObj: public BitObjHolder<BinObjTag, T, Bits>
59 
60  struct HexObjTag {}; ///< Tag object for `HexObj`.
61  /// Holder for data to be presented in hexadecimal format (base 16).
62  template <typename T, unsigned int const Bits = (8*sizeof(T))>
63  struct HexObj: public BitObjHolder<HexObjTag, T, Bits>
65 
66  /**
67  * @brief Wrapper to have data printed as hexadecimal dump.
68  * @param Atom base type of the dump
69  *
70  * This record points to the data to be dumped, and it also include some
71  * dumping parameters:
72  * * `size`: how many atoms are present in the data
73  * * `columns`: how many atoms to print on each line
74  *
75  * The data is interpreted as a sequence of `Atom` types.
76  * Supported `Atom` types are unsigned integral types (`std::uint8_t`,
77  * `std::uint16_t`, etc.). Each atom is dumped as an `HexObj`.
78  */
79  template <typename Atom>
80  struct HexDumper {
81 
82  Atom const* const data;
83  std::size_t const size;
84  unsigned int const columns { 16U };
85 
86  HexDumper(Atom const* data, std::size_t size, unsigned int columns = 16U)
87  : data(data), size(size), columns(columns) {}
88 
89  }; // HexDumper
90 
91 
92  /**
93  * @brief A wrapper padding the dump of its data with zeroes (or `C`).
94  * @tparam T type of data to be dumped
95  * @tparam Fill (default: `0`) fill character
96  * @see `icarus::ns::util::zeropad()`
97  *
98  * The wrapper allows zero-padding of data with a specified field width.
99  */
100  template <typename T, char Fill = '0'>
101  struct ZeroPadder {
102  T const data;
103  unsigned int const field;
104  char const pad;
105 
106  ZeroPadder(T data, unsigned int field, char pad = Fill)
107  : data(data), field(field), pad(pad) {}
108 
109  }; // struct ZeroPadder
110 
111 
112  /// An object representing `N` characters of value `C`.
113  template <unsigned int N, char C = ' '>
114  struct Blanks {};
115 
116 
117  /// @}
118  // --- END -- Wrapping objects -----------------------------------------------
119 
120 
121  /// Returns a bit mask of type `T` with the four most significant bits set.
122  template <typename T>
123  constexpr T fourMSBmask();
124 
125  /// Prints a zero-padded integral `value` into `out`.
126  template <typename T>
127  void printHex(std::ostream& out, T value);
128 
129 
130  // --- BEGIN -- dump operators -----------------------------------------------
131 
132  /// Dumps `N` characters of value `C` to `out` stream.
133  template <unsigned int N, char C = ' '>
134  std::ostream& operator<< (std::ostream& out, Blanks<N, C>);
135 
136 
137  /**
138  * @brief Dumps `data` bit by bit into `out` stream.
139  * @param out output stream
140  * @param data data wrapper with information on how many bits to dump
141  * @return the output stream `out`
142  *
143  * Parameters of the dump are read from the `data` wrapper.
144  * The dump is in format `(Bits) bbb bbbb bbbb ...` (`Bits` is the number
145  * of bits, and `b` are bit values, `0` or `1`, the first being the most
146  * significant bit).
147  */
148  template <typename T, unsigned int Bits>
149  std::ostream& operator<< (std::ostream& out, BinObj<T, Bits> const& data);
150 
151 
152  /**
153  * @brief Dumps `data` nibble by nibble into `out` stream.
154  * @param out output stream
155  * @param data data wrapper
156  * @return the output stream `out`
157  *
158  * The value in `data` is printed in hexadecimal format, including all its
159  * bits.
160  * The STL `std::hex` mode of a stream may be more convenient,
161  * but it's sticky:
162  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
163  * using namespace icarus::ns::util;
164  * std::cout << 36 << std::endl; // "36"
165  * std::cout << details::HexObj{ 36 } << std::endl; // 00000024
166  * std::cout << 36 << std::endl; // "36"
167  * std::cout << std::hex << 36 << std::endl; // "24"
168  * std::cout << 36 << std::endl; // "24" (std::hex is sticky)
169  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
170  * Parameters of the dump are read from the `data` wrapper.
171  * The dump is in format `(Bits) bbb bbbb bbbb ...` (`Bits` is the number
172  * of bits, and `b` are bit values, `0` or `1`, the first being the most
173  * significant bit).
174  */
175  template <typename T>
176  std::ostream& operator<< (std::ostream& out, HexObj<T> const& data);
177 
178 
179  /**
180  * @brief Dumps data in a hexadecimal table.
181  * @param out output stream
182  * @param data data wrapper with information on how to dump it
183  * @return the output stream `out`
184  *
185  * Wrapped data is printed in a table: address of the first `Atom` of data,
186  * a separator `|`, a sequence of as many atom values as specified in
187  * `data.columns`, in hexadecimal format and zero-padded, and another
188  * separator `|`.
189  * If there are 6 or more columns, a larger space indentation is inserted
190  * between the two central columns.
191  * The table is written on a new line, and the line is ended after the table.
192  */
193  template <typename Atom>
194  std::ostream& operator<< (std::ostream& out, HexDumper<Atom> const& data);
195 
196  /// Dumps a value padding with `0` via `ZeroPadder` wrapper.
197  template <typename T>
198  std::ostream& operator<< (std::ostream& out, ZeroPadder<T> const& data);
199 } // namespace icarus::ns::util::details
200 
201 
202 // -----------------------------------------------------------------------------
203 namespace icarus::ns::util {
204 
205  template <typename IOS>
207 
208 
209  // --- BEGIN -- Format adapters ----------------------------------------------
210  /**
211  * @name Format adapters
212  *
213  * These functions should be used in stream insertion statements like:
214  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
215  * std::cout << icarus::ns::util::bin(0xAA) << std::endl;
216  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
217  *
218  */
219  /// @{
220 
221  /**
222  * @brief Returns a wrapper to print the specified data in binary format.
223  * @tparam T type of datum to be printed
224  * @param value the value to be printed
225  * @see `icarus::ns::util::details::operator<< (std::ostream&, icarus::ns::util::details::BinObj<T, Bits> const&)` *
226  * Example:
227  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
228  * std::cout << icarus::ns::util::bin(0xAA) << std::endl;
229  * std::cout << icarus::ns::util::bin<char>(0xAA) << std::endl;
230  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
231  * will print `(32) 0000 0000 0000 0000 0000 0000 1010 1010` on the first line
232  * (assuming the representation of `int` is 32 bit) and `(8) 1010 1010` on the
233  * second line.
234  */
235  template <typename T>
236  constexpr details::BinObj<T> bin(T value);
237 
238  /**
239  * @brief Returns a wrapper to print the specified data in binary format.
240  * @tparam Bits number of bits to print out of the type `T`
241  * @tparam T type of datum to be printed
242  * @param value the value to be printed
243  * @see `icarus::ns::util::details::operator<< (std::ostream&, icarus::ns::util::details::BinObj<T, Bits> const&)`
244  *
245  * Only the least significant `Bits` will be printed.
246  *
247  * Example:
248  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
249  * std::cout << icarus::ns::util::bin<10U>(0xAA) << std::endl;
250  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
251  * will print `(10) 00 1010 1010`.
252  */
253  template <std::size_t Bits, typename T>
254  constexpr details::BinObj<T, Bits> bin(T value);
255 
256  /**
257  * @brief Returns a wrapper to print the specified data in hex dump format.
258  * @tparam Atom type of basic element of the data
259  * @param data pointer to the data to be printed
260  * @param size number of elements to be printed
261  * @param columns (default: `16`) atoms per output line
262  * @see `icarus::ns::util::details::operator<< (std::ostream&, icarus::ns::util::details::HexDumper<Atom> const&)`
263  *
264  *
265  *
266  * Only the least significant `Bits` will be printed.
267  *
268  * Example:
269  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
270  * const char data[] = "012345";
271  * std::cout << icarus::ns::util::hexdump(data, 7U, 8U) << std::endl;
272  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
273  * will print 7 bytes from `data`, using a 8 column format, with an output
274  * similar to:
275  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
276  * 0X81234560 | 30 31 32 33 34 35 00 |
277  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
278  * while
279  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
280  * const std::uint16_t powers[]
281  * = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
282  * std::cout << icarus::ns::util::hexdump(powers, 13U, 8U) << std::endl;
283  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
284  * will print 13 values from `data`, using a 8 column format, with an output
285  * similar to:
286  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
287  * 0X81234570 | 0001 0002 0004 0008 0010 0020 0040 0080 |
288  * 0X81234580 | 0100 0200 0400 0800 1000 |
289  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
290  */
291  template <typename Atom>
293  (Atom const* data, std::size_t size, unsigned int columns = 16U);
294 
295  /**
296  * @brief Returns a wrapper to print the specified data with a field width
297  * @tparam T type of data to be printed
298  * @param data value to be printed
299  * @param field number of characters to use
300  * @param pad (default: `0`) filling character
301  * @return object to be inserted into a stream
302  *
303  * The specified `value` is printed right-padded into a space at least `field`
304  * character wide, using `pad` as filling character on the left of `value`.
305  *
306  * C++ STL I/O is used to produce the output.
307  * Example:
308  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
309  * std::cout << icarus::ns::util::zeropad(79, 4) << std::endl;
310  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
311  * will print `0079` while
312  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
313  * std::cout << std::hex << icarus::ns::util::zeropad(79, 4, '*') << std::endl;
314  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
315  * will print `**4F`.
316  */
317  template <typename T>
318  details::ZeroPadder<T> zeropad(T data, unsigned int field, char pad = '0');
319 
320  /// @}
321  // --- END -- Format adapters ------------------------------------------------
322 
323 } // namespace icarus::ns::util
324 
325 
326 // -----------------------------------------------------------------------------
327 /**
328  * @brief Saves some status of the specified stream object, and restores it.
329  * @tparam IOS type of stream object, with flag interface like `std::ostream`
330  *
331  * This object uses the RIIA pattern to read some status from a stream, and then
332  * restore it on the destruction of the object itself.
333  * Example:
334  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
335  * std::cout << std::hex << 26 << std::endl; // prints "1a"
336  * std::cout << 28 << std::endl; // prints "1c" (hexadecimal format sticks)
337  * {
338  * icarus::ns::util::FormatFlagsGuard sg(std::cout); // saves std::cout status
339  * std::cout << std::oct << 26 << std::endl; // prints "32"
340  * std::cout << 28 << std::endl; // prints "34" (octal format sticks)
341  * // destruction of sg happens here, std::cout flags are restored
342  * }
343  * std::cout << 28 << std::endl; // prints "1c" (hexadecimal format restored)
344  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
345  *
346  * Saved settings currently include:
347  * * all format flags (`std::ios_base::flags()`)
348  * * fill character (`std::basic_ios::fill()`)
349  *
350  */
351 template <typename IOS>
353  static_assert(!std::is_const_v<IOS>);
354 
355  IOS& ios;
356  typename IOS::fmtflags const flags;
357  typename IOS::char_type const fill;
358 
359  public:
361  : ios{ios}, flags{ios.flags()}, fill{ios.fill()} {}
362 
364 
365  void restore() { ios.flags(flags); ios.fill(fill); }
366 
367 }; // struct icarus::ns::util::FormatFlagsGuard
368 
369 
370 // -----------------------------------------------------------------------------
371 template <typename T>
372 void icarus::ns::util::details::printHex(std::ostream& out, T value) {
373  static_assert(std::is_integral_v<T>, "Only integral types are supported.");
374 
375  // we actually store the null character at the end; it does not really matter
376  constexpr const char HexChars[17U] = "0123456789ABCDEF";
377 
378  // print nibble by nibble, no spaces, starting from the most significant
379  std::size_t nibblesLeft = sizeof(value) * 2U;
380  while (nibblesLeft--) {
381  std::size_t const digit = (value >> (nibblesLeft * 4U)) & 0xF;
382  out << HexChars[digit];
383  } // while
384 } // icarus::ns::util::details::printHex()
385 
386 
387 // -----------------------------------------------------------------------------
388 template <unsigned int N, char C >
389 std::ostream& icarus::ns::util::details::operator<<
390  (std::ostream& out, Blanks<N, C>)
391 {
392  for (unsigned int i = 0U; i < N; ++i) out.put(C);
393  return out;
394 } // icarus::ns::util::details::operator<< (icarus::ns::util::details::Blanks)
395 
396 
397 // -----------------------------------------------------------------------------
398 template <typename T, unsigned int Bits>
399 std::ostream& icarus::ns::util::details::operator<<
400  (std::ostream& out, BinObj<T, Bits> const& data)
401 {
402  static_assert(std::is_integral_v<T>);
403  static_assert(Bits > 0U);
404 
405  unsigned int bitsLeft = data.bits;
406  T mask = T{ 1 } << (bitsLeft - 1);
407  out << "(" << bitsLeft << ") ";
408  while (mask) {
409  out << ((data.data & mask)? '1': '0');
410  mask >>= 1;
411  if (--bitsLeft == 0) break;
412  if ((bitsLeft & 0x03) == 0x00) out << ' ';
413  } // while
414  return out;
415 } // icarus::ns::util::details::operator<< (icarus::ns::util::details::BinObj)
416 
417 
418 // -----------------------------------------------------------------------------
419 template <typename T>
420 std::ostream& icarus::ns::util::details::operator<<
421  (std::ostream& out, HexObj<T> const& data)
422  { printHex(out, data.data); return out; }
423 
424 
425 // -----------------------------------------------------------------------------
426 template <typename Atom>
427 std::ostream& icarus::ns::util::details::operator<<
428  (std::ostream& out, HexDumper<Atom> const& data)
429 {
430 
431  static constexpr std::size_t AtomChars = sizeof(Atom) * 2;
432  static constexpr Blanks<AtomChars> BlankAtom;
433 
434  auto const printAtoms = [&out]
435  (Atom const* ptr, Atom const* const ptrend, std::ptrdiff_t columns)
436  {
437  /*
438  FormatFlagsGuard const outGuard { out };
439  out.setf(std::ios_base::hex, std::ios_base::basefield);
440  out.unsetf(std::ios_base::showbase);
441  out.fill('0');
442  */
443  Atom const* cend = ptr + columns;
444  while (ptr != cend) {
445  out << ' ';
446  if (ptr < ptrend) {
447  // out << std::setw(AtomChars) << *ptr;
448  printHex(out, *ptr);
449  }
450  else out << BlankAtom;
451  ++ptr;
452  } // while
453  return ptr;
454  };
455 
456  Atom const* ptr = data.data;
457  Atom const* const ptrend = ptr + data.size;
458 
459  FormatFlagsGuard const outGuard { out };
460  out.fill('0');
461 
462  auto const halfColumns = data.columns / 2;
463  while (ptr < ptrend) {
464 
465  out << "\n" << std::setw(8) << ((void*) ptr) << " |";
466 
467  ptr = printAtoms(ptr, ptrend, data.columns - halfColumns);
468  if (data.columns >= 6U) out << ' ';
469  ptr = printAtoms(ptr, ptrend, halfColumns);
470  out << " |";
471 
472  } // while
473 
474  out << '\n';
475 
476  return out;
477 } // operator<< (HexDumper)
478 
479 
480 // -----------------------------------------------------------------------------
481 template <typename T>
482 std::ostream& icarus::ns::util::details::operator<<
483  (std::ostream& out, ZeroPadder<T> const& data)
484 {
485  FormatFlagsGuard ffg { out };
486  out.fill(data.pad);
487  return out << std::setw(data.field) << data.data;
488 } // icarus::ns::util::details::operator<< (ZeroPadder)
489 
490 
491 
492 // -----------------------------------------------------------------------------
493 template <typename T>
495  { return details::BinObj<T>{ std::move(value) }; }
496 
497 template <std::size_t Bits, typename T>
498 constexpr auto icarus::ns::util::bin(T value) -> details::BinObj<T, Bits>
499  { return details::BinObj<T, Bits>{ std::move(value) }; }
500 
501 
502 // -----------------------------------------------------------------------------
503 template <typename Atom>
505  (Atom const* data, std::size_t size, unsigned int columns /* = 16U */)
506  -> details::HexDumper<Atom>
507  { return details::HexDumper<Atom>{ data, size, columns }; }
508 
509 
510 // -----------------------------------------------------------------------------
511 template <typename T>
512 auto icarus::ns::util::zeropad(T data, unsigned int field, char pad /* = '0' */)
513  -> details::ZeroPadder<T>
514  { return details::ZeroPadder<T>{ data, field, pad }; }
515 
516 
517 // -----------------------------------------------------------------------------
518 
519 #endif // ICARUSALG_UTILITIES_BINARYDUMPUTILS_H
An object wrapping some data (copy), with a tag type.
details::HexDumper< Atom > hexdump(Atom const *data, std::size_t size, unsigned int columns=16U)
Returns a wrapper to print the specified data in hex dump format.
std::size_t size(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:561
HexDumper(Atom const *data, std::size_t size, unsigned int columns=16U)
void printHex(std::ostream &out, T value)
Prints a zero-padded integral value into out.
auto cend(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:579
constexpr details::BinObj< T > bin(T value)
Returns a wrapper to print the specified data in binary format.
constexpr mask_t< EnumType > mask(EnumType bit, OtherBits...otherBits)
Returns a mask with all specified bits set.
Holder for data to be presented in binary format (base 2).
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker see the discussion of warn common echo in *Note Linker such as a global int variable echo as opposed to a large global array echo echo I echo The symbol is an indirect reference to another symbol This echo is a GNU extension to the a out object file format which is echo rarely used echo echo N echo The symbol is a debugging symbol echo echo R echo The symbol is in a read only data section echo echo S echo The symbol is in an uninitialized data section for small echo objects echo echo T echo The symbol is in the the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo W echo The symbol is a weak symbol that has not been specifically echo tagged as a weak object symbol When a weak defined symbol echo is linked with a normal defined the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo echo The symbol is a stabs symbol in an a out object file In echo this the next values printed are the stabs other field
Holder for data to be presented in hexadecimal format (base 16).
Wrapper to have data printed as hexadecimal dump.
Saves some status of the specified stream object, and restores it.
constexpr T fourMSBmask()
Returns a bit mask of type T with the four most significant bits set.
ZeroPadder(T data, unsigned int field, char pad=Fill)
An object representing N characters of value C.
process_name largeant stream1 can override from command line with o or output physics producers generator N
details::ZeroPadder< T > zeropad(T data, unsigned int field, char pad= '0')
Returns a wrapper to print the specified data with a field width.
temporary value
A wrapper padding the dump of its data with zeroes (or C).
static constexpr unsigned int bits