23 #ifndef GUL14_HEXDUMP_H_
24 #define GUL14_HEXDUMP_H_
28 #include <type_traits>
58 template <
typename T,
typename =
int>
59 struct IsHexDumpContainer : std::false_type { };
62 struct IsHexDumpContainer <T,
63 typename std::enable_if_t<
64 std::is_integral<typename std::iterator_traits<decltype(
65 std::declval<T>().cbegin())>::value_type>::value,
66 decltype(std::declval<T>().cbegin(),
67 std::declval<T>().cend(),
79 template <
typename T,
typename =
int>
80 struct IsHexDumpIterator : std::false_type { };
83 struct IsHexDumpIterator <T,
84 typename std::enable_if_t<
85 std::is_integral<typename std::iterator_traits<T>::value_type>::value
86 and not std::is_same<typename std::iterator_traits<T>::iterator_category,
87 std::input_iterator_tag>::value,
88 decltype(std::declval<T>().operator*(),
89 std::declval<T>().operator++(),
95 struct IsHexDumpIterator <T,
96 typename std::enable_if_t<
97 std::is_pointer<T>::value
98 and std::is_integral<typename std::remove_pointer<T>::type>::value,
101 : std::true_type { };
104 template <
typename StreamT,
105 typename = std::enable_if_t<std::is_convertible<
107 std::basic_ostream<
typename StreamT::char_type,
108 typename StreamT::traits_type>*>::value>>
109 struct IsHexDumpStream : std::true_type { };
115 template<
typename StreamT,
typename IteratorT,
116 typename = std::enable_if_t<detail::IsHexDumpStream<StreamT>::value>,
117 typename = std::enable_if_t<detail::IsHexDumpIterator<IteratorT>::value>>
118 StreamT&
hexdump_stream(StreamT& dest,
const IteratorT& begin,
const IteratorT& end,
121 constexpr
auto maxelem = 1000ul * 16;
124 constexpr
auto nod =
sizeof(*begin) * 2;
125 constexpr
bool is_char = (nod == 2);
127 const std::string indent(prompt.length(),
' ');
128 const std::string empty(nod + 1,
' ');
130 dest << std::hex << std::setfill(
'0');
132 auto it = IteratorT{ begin };
135 for (
size_t i = 0; (it != end and i < maxelem) or (i == 0); i += 16) {
136 dest << (i ? indent : prompt) << std::setw(6) << i <<
": ";
138 for (
size_t j = 0; j < 16; ++j) {
140 const unsigned long long ch =
static_cast<
141 typename std::make_unsigned<
142 typename std::decay<decltype(*it)
>::type
145 dest << std::setw(nod) << ch <<
' ';
157 for (
size_t j = 0; j < 16 and line != end; ++j, ++line) {
158 const auto c =
static_cast<unsigned char>(*line);
159 dest << static_cast<char>(isprint(c) ? c :
'.');
165 dest << indent <<
"[output truncated...]\n";
211 template<
typename IteratorT,
212 typename = std::enable_if_t<detail::IsHexDumpIterator<IteratorT>::value>>
215 std::stringstream o{ };
228 template<
typename ContainerT,
229 typename = std::enable_if_t<detail::IsHexDumpContainer<ContainerT>::value>>
232 std::stringstream o{ };
249 template<
typename IteratorT,
typename ContainerT =
void*>
273 IteratorT begin_it, IteratorT end_it, std::string prompt, ContainerT&& cont)
276 ,
prompt_ { std::move(prompt) }
277 ,
cont_ { std::forward<ContainerT>(cont) }
279 regenerate_iterators<ContainerT>();
294 *
this = std::move(other);
311 regenerate_iterators<ContainerT>();
325 begin_ = std::move(other.begin_);
326 end_ = std::move(other.end_);
327 prompt_ = std::move(other.prompt_);
328 cont_ = std::move(other.cont_);
330 regenerate_iterators<ContainerT>();
351 template <
typename ContType,
352 std::enable_if_t<!detail::IsHexDumpContainer<ContType>::value,
int> = 0
354 void regenerate_iterators() noexcept
361 template <
typename ContType,
362 std::enable_if_t<detail::IsHexDumpContainer<ContType>::value,
int> = 0
364 void regenerate_iterators() noexcept
413 template<
typename IteratorT,
414 typename = std::enable_if_t<detail::IsHexDumpIterator<IteratorT>::value>>
415 HexdumpParameterForward<const IteratorT>
416 hexdump_stream(
const IteratorT& begin,
const IteratorT& end, std::string prompt =
"")
418 return { begin, end, std::move(prompt),
nullptr };
429 template<
typename ContainerT,
430 typename = std::enable_if_t<detail::IsHexDumpContainer<ContainerT>::value>>
431 HexdumpParameterForward<const decltype(std::declval<ContainerT>().cbegin())>
434 return { cont.cbegin(), cont.cend(), std::move(prompt),
nullptr };
445 template<
typename ContainerT,
446 typename = std::enable_if_t<detail::IsHexDumpContainer<ContainerT>::value,
447 decltype(HexdumpParameterForward<decltype(std::declval<ContainerT>().cbegin()),
449 HexdumpParameterForward<decltype(std::declval<ContainerT>().cbegin()), ContainerT>
454 return { cont.cbegin(), cont.cbegin(), std::move(prompt),
455 std::forward<ContainerT>(cont) };
Helper object used to enable a convenient syntax to dump things to a stream.
Definition: hexdump.h:250
HexdumpParameterForward & operator=(HexdumpParameterForward &&other) noexcept
Move assignment (automatically updates the begin_ and end_ interator members if the moved-from object...
Definition: hexdump.h:320
HexdumpParameterForward(const HexdumpParameterForward &other)
Copy constructor (automatically updates the begin_ and end_ interator members if the copied object ho...
Definition: hexdump.h:286
IteratorT begin_
Iterator to begin of elements to be dumped (in iterator mode)
Definition: hexdump.h:253
std::string prompt_
Possible prompt to prepend to the dump.
Definition: hexdump.h:257
HexdumpParameterForward(HexdumpParameterForward &&other) noexcept
Move constructor (automatically updates the begin_ and end_ interator members if the moved-from objec...
Definition: hexdump.h:292
IteratorT end_
Iterator past end of elements to be dumped (in iterator mode)
Definition: hexdump.h:255
HexdumpParameterForward(IteratorT begin_it, IteratorT end_it, std::string prompt, ContainerT &&cont)
Construct a hexdump parameter forwarder object.
Definition: hexdump.h:272
HexdumpParameterForward & operator=(const HexdumpParameterForward &other)
Copy assignment (automatically updates the begin_ and end_ interator members if the copied object hol...
Definition: hexdump.h:301
friend std::ostream & operator<<(std::ostream &os, const HexdumpParameterForward< IteratorT, ContainerT > &hdp)
Overload of std::ostream's operator<< to enable a convenient syntax to dump things to a stream.
Definition: hexdump.h:344
ContainerT cont_
A container with the elements to be dumped (in container/temporary mode)
Definition: hexdump.h:259
Definition of macros used internally by GUL.
Namespace gul14 contains all functions and classes of the General Utility Library.
Definition: doxygen.h:26
std::string hexdump(IteratorT begin, IteratorT end, string_view prompt="")
Generate a hexdump of a data range and return it as a string.
Definition: hexdump.h:213
basic_string_view< char > string_view
A view to a contiguous sequence of chars.
Definition: string_view.h:623
HexdumpParameterForward< decltype(std::declval< ContainerT >).cbegin()), ContainerT > hexdump_stream(ContainerT &&cont, std::string prompt="")
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: hexdump.h:450
HexdumpParameterForward< const IteratorT > hexdump_stream(const IteratorT &begin, const IteratorT &end, std::string prompt="")
Generate a hexdump of a data range that can be efficiently written to a stream using operator<<.
Definition: hexdump.h:416
Provides a gul14::string_view that is fully compatible with C++17's std::string_view.