23 #ifndef GUL14_HEXDUMP_H_
24 #define GUL14_HEXDUMP_H_
28 #include <type_traits>
65 template <
typename T,
typename =
int>
66 struct IsHexDumpContainer : std::false_type { };
69 struct IsHexDumpContainer <T,
70 typename std::enable_if_t<
71 std::is_integral<typename std::iterator_traits<decltype(
72 std::declval<T>().cbegin())>::value_type>::value,
73 decltype(std::declval<T>().cbegin(),
74 std::declval<T>().cend(),
86 template <
typename T,
typename =
int>
87 struct IsHexDumpIterator : std::false_type { };
90 struct IsHexDumpIterator <T,
91 typename std::enable_if_t<
92 std::is_integral<typename std::iterator_traits<T>::value_type>::value
93 and not std::is_same<typename std::iterator_traits<T>::iterator_category,
94 std::input_iterator_tag>::value,
95 decltype(std::declval<T>().operator*(),
96 std::declval<T>().operator++(),
101 template <
typename T>
102 struct IsHexDumpIterator <T,
103 typename std::enable_if_t<
104 std::is_pointer<T>::value
105 and std::is_integral<typename std::remove_pointer<T>::type>::value,
108 : std::true_type { };
111 template <
typename StreamT,
112 typename = std::enable_if_t<std::is_convertible<
114 std::basic_ostream<
typename StreamT::char_type,
115 typename StreamT::traits_type>*>::value>>
116 struct IsHexDumpStream : std::true_type { };
122 template<
typename StreamT,
typename IteratorT,
123 typename = std::enable_if_t<detail::IsHexDumpStream<StreamT>::value>,
124 typename = std::enable_if_t<detail::IsHexDumpIterator<IteratorT>::value>>
125 StreamT&
hexdump_stream(StreamT& dest,
const IteratorT& begin,
const IteratorT& end,
128 constexpr
auto maxelem = 1000ul * 16;
131 constexpr
auto nod =
sizeof(*begin) * 2;
132 constexpr
bool is_char = (nod == 2);
134 const std::string indent(prompt.length(),
' ');
135 const std::string empty(nod + 1,
' ');
137 dest << std::hex << std::setfill(
'0');
139 auto it = IteratorT{ begin };
142 for (
size_t i = 0; (it != end and i < maxelem) or (i == 0); i += 16) {
143 dest << (i ? indent : prompt) << std::setw(6) << i <<
": ";
145 for (
size_t j = 0; j < 16; ++j) {
147 const unsigned long long ch =
static_cast<
148 typename std::make_unsigned<
149 typename std::decay<decltype(*it)
>::type
152 dest << std::setw(nod) << ch <<
' ';
164 for (
size_t j = 0; j < 16 and line != end; ++j, ++line) {
165 const auto c =
static_cast<unsigned char>(*line);
166 dest << static_cast<char>(isprint(c) ? c :
'.');
172 dest << indent <<
"[output truncated...]\n";
218 template<
typename IteratorT,
219 typename = std::enable_if_t<detail::IsHexDumpIterator<IteratorT>::value>>
222 std::stringstream o{ };
235 template<
typename ContainerT,
236 typename = std::enable_if_t<detail::IsHexDumpContainer<ContainerT>::value>>
239 std::stringstream o{ };
256 template<
typename IteratorT,
typename ContainerT =
void*>
280 IteratorT begin_it, IteratorT end_it, std::string prompt, ContainerT&& cont)
283 ,
prompt_ { std::move(prompt) }
284 ,
cont_ { std::forward<ContainerT>(cont) }
286 regenerate_iterators<ContainerT>();
301 *
this = std::move(other);
318 regenerate_iterators<ContainerT>();
332 begin_ = std::move(other.begin_);
333 end_ = std::move(other.end_);
334 prompt_ = std::move(other.prompt_);
335 cont_ = std::move(other.cont_);
337 regenerate_iterators<ContainerT>();
358 template <
typename ContType,
359 std::enable_if_t<!detail::IsHexDumpContainer<ContType>::value,
int> = 0
361 void regenerate_iterators() noexcept
368 template <
typename ContType,
369 std::enable_if_t<detail::IsHexDumpContainer<ContType>::value,
int> = 0
371 void regenerate_iterators() noexcept
420 template<
typename IteratorT,
421 typename = std::enable_if_t<detail::IsHexDumpIterator<IteratorT>::value>>
422 HexdumpParameterForward<const IteratorT>
423 hexdump_stream(
const IteratorT& begin,
const IteratorT& end, std::string prompt =
"")
425 return { begin, end, std::move(prompt),
nullptr };
436 template<
typename ContainerT,
437 typename = std::enable_if_t<detail::IsHexDumpContainer<ContainerT>::value>>
438 HexdumpParameterForward<const decltype(std::declval<ContainerT>().cbegin())>
441 return { cont.cbegin(), cont.cend(), std::move(prompt),
nullptr };
452 template<
typename ContainerT,
453 typename = std::enable_if_t<detail::IsHexDumpContainer<ContainerT>::value,
454 decltype(HexdumpParameterForward<decltype(std::declval<ContainerT>().cbegin()),
456 HexdumpParameterForward<decltype(std::declval<ContainerT>().cbegin()), ContainerT>
461 return { cont.cbegin(), cont.cbegin(), std::move(prompt),
462 std::forward<ContainerT>(cont) };
Helper object used to enable a convenient syntax to dump things to a stream.
Definition: hexdump.h:257
HexdumpParameterForward & operator=(HexdumpParameterForward &&other) noexcept
Move assignment (automatically updates the begin_ and end_ interator members if the moved-from object...
Definition: hexdump.h:327
HexdumpParameterForward(const HexdumpParameterForward &other)
Copy constructor (automatically updates the begin_ and end_ interator members if the copied object ho...
Definition: hexdump.h:293
IteratorT begin_
Iterator to begin of elements to be dumped (in iterator mode)
Definition: hexdump.h:260
std::string prompt_
Possible prompt to prepend to the dump.
Definition: hexdump.h:264
HexdumpParameterForward(HexdumpParameterForward &&other) noexcept
Move constructor (automatically updates the begin_ and end_ interator members if the moved-from objec...
Definition: hexdump.h:299
IteratorT end_
Iterator past end of elements to be dumped (in iterator mode)
Definition: hexdump.h:262
HexdumpParameterForward(IteratorT begin_it, IteratorT end_it, std::string prompt, ContainerT &&cont)
Construct a hexdump parameter forwarder object.
Definition: hexdump.h:279
HexdumpParameterForward & operator=(const HexdumpParameterForward &other)
Copy assignment (automatically updates the begin_ and end_ interator members if the copied object hol...
Definition: hexdump.h:308
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:351
ContainerT cont_
A container with the elements to be dumped (in container/temporary mode)
Definition: hexdump.h:266
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:220
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:457
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:423
basic_string_view< char > string_view
A view to a contiguous sequence of chars.
Definition: string_view.h:624
Definition of macros used internally by GUL.
Namespace gul14 contains all functions and classes of the General Utility Library.
Definition: doxygen.h:26
Provides a gul14::string_view that is fully compatible with C++17's std::string_view.