14 #include <type_traits>
17 #ifdef __SIZEOF_INT128__
18 #define BITCPY_INT128_CONDITIONAL_DEFINE(...) __VA_ARGS__
20 #define BITCPY_INT128_CONDITIONAL_DEFINE_C(...) __VA_ARGS__ static_assert(true, "")
23 #define BITCPY_INT128_CONDITIONAL_DEFINE(...)
25 #define BITCPY_INT128_CONDITIONAL_DEFINE_C(...) static_assert(true, "")
32 namespace bitprint_detail
37 using type =
typename std::make_signed<T>::type;
39 BITCPY_INT128_CONDITIONAL_DEFINE_C(
41 struct make_signed<__uint128_t> {
42 using type = __int128_t;
47 using type =
typename std::make_unsigned<T>::type;
49 BITCPY_INT128_CONDITIONAL_DEFINE_C(
51 struct make_unsigned<__uint128_t> {
52 using type = __uint128_t;
55 struct make_unsigned<__int128_t> {
56 using type = __uint128_t;
59 struct make_unsigned<float>
61 using type = uint32_t;
64 struct make_unsigned<double>
66 using type = uint64_t;
68 template <
bool use_brackets>
69 void print_bracket_newline(
const bool add_newline)
72 printf((add_newline ?
"}\n" :
"}"));
81 inline void printhex(
const uint8_t data,
const bool add_newline =
true)
84 printf(
"0x%02" PRIX8
"\n", data);
86 printf(
"0x%02" PRIX8, data);
92 inline void printhex(
const uint16_t data,
const bool add_newline =
true)
95 printf(
"0x%04" PRIX16
"\n", data);
97 printf(
"0x%04" PRIX16, data);
103 inline void printhex(
const uint32_t data,
const bool add_newline =
true)
106 printf(
"0x%08" PRIX32
"\n", data);
108 printf(
"0x%08" PRIX32, data);
114 inline void printhex(
const uint64_t data,
const bool add_newline =
true)
117 printf(
"0x%08" PRIX32
"%08" PRIX32
"\n",
118 static_cast<uint32_t
>(data >> 32),
119 static_cast<uint32_t
>(data));
121 printf(
"0x%08" PRIX32
"%08" PRIX32,
122 static_cast<uint32_t
>(data >> 32),
123 static_cast<uint32_t
>(data));
125 BITCPY_INT128_CONDITIONAL_DEFINE_C(
128 inline void printhex(
const __uint128_t data,
const bool add_newline =
true)
131 printf(
"0x%08" PRIX32
"%08" PRIX32
"%08" PRIX32
"%08" PRIX32
"\n",
132 static_cast<uint32_t
>(data >> 32 * 3),
133 static_cast<uint32_t
>(data >> 32 * 2),
134 static_cast<uint32_t
>(data >> 32 * 1),
135 static_cast<uint32_t
>(data));
137 printf(
"0x%08" PRIX32
"%08" PRIX32
"%08" PRIX32
"%08" PRIX32,
138 static_cast<uint32_t
>(data >> 32 * 3),
139 static_cast<uint32_t
>(data >> 32 * 2),
140 static_cast<uint32_t
>(data >> 32 * 1),
141 static_cast<uint32_t
>(data));
147 inline void printhex(
const bool data,
const bool add_newline =
true)
149 printhex(uint8_t(data), add_newline);
155 template <
typename T = void,
156 typename std::enable_if<
157 std::is_enum<T>::value
158 || std::is_signed<T>::value
159 BITCPY_INT128_CONDITIONAL_DEFINE(|| std::is_same<T, __int128_t>::value),
160 T>::type * =
nullptr>
161 void printhex(
const T data,
const bool add_newline =
true)
163 typedef typename bitprint_detail::make_unsigned<T>::type data_as_unsigned_type;
167 data_as_unsigned_type unsigned_value;
169 punned_data.original_value = data;
170 printhex(punned_data.unsigned_value, add_newline);
177 template <
bool use_brackets = true,
typename T =
void,
size_t N = 0u>
178 void printhex(
const T (&data)[N],
const bool add_newline =
true)
182 for (
size_t i = 0; i < N; i++)
185 printf(
"%s", (i + 1u < N ?
", " :
""));
187 bitprint_detail::print_bracket_newline<use_brackets>(add_newline);
190 namespace bitprint_detail
193 template <
typename...>
194 using void_t_test = void;
197 template <
typename T,
typename =
void>
198 struct has_data_and_size : std::false_type
201 template <
typename T>
202 struct has_data_and_size<
204 decltype(std::declval<
typename std::remove_cv<
typename std::remove_reference<T>::type>::type>().data()),
205 decltype(std::declval<
typename std::remove_cv<
typename std::remove_reference<T>::type>::type>().size())>>
215 template <
bool use_brackets =
true,
typename T = void,
216 typename std::enable_if<bitprint_detail::has_data_and_size<T>::value,
int>::type * =
nullptr>
217 void printhex(
const T& data,
const bool add_newline =
true)
221 const size_t N = data.size();
222 for (
size_t i = 0; i < N; i++)
225 printf(
"%s", (i + 1u < N ?
", " :
""));
227 bitprint_detail::print_bracket_newline<use_brackets>(add_newline);
235 template <
bool use_brackets = true,
typename T =
void,
size_t N = 0u>
236 void printhex(
const T (&data)[N],
size_t size,
const bool add_newline =
true)
242 for (
size_t i = 0; i < size; i++)
245 printf(
"%s", (i + 1u < size ?
", " :
""));
247 bitprint_detail::print_bracket_newline<use_brackets>(add_newline);
254 template <
bool use_brackets = true,
typename T =
void,
size_t N = 0u>
255 void printbin(
const T (&data)[N],
const bool add_newline =
true)
259 for (
size_t i = 0; i < N; i++)
261 for (
size_t ii = 0; ii <
sizeof(T); ii++)
263 const uint8_t data_element =
static_cast<uint8_t
>(
264 (data[i] >> (
sizeof(T) * 8 - (ii + 1) * 8)) & 0xFFu);
265 printf(
"%c%c%c%c%c%c%c%c",
266 ((data_element & 0x80u) ?
'1' :
'0'),
267 ((data_element & 0x40u) ?
'1' :
'0'),
268 ((data_element & 0x20u) ?
'1' :
'0'),
269 ((data_element & 0x10u) ?
'1' :
'0'),
270 ((data_element & 0x08u) ?
'1' :
'0'),
271 ((data_element & 0x04u) ?
'1' :
'0'),
272 ((data_element & 0x02u) ?
'1' :
'0'),
273 ((data_element & 0x01u) ?
'1' :
'0'));
275 printf(
"%s", (i + 1u < N ?
", " :
""));
277 bitprint_detail::print_bracket_newline<use_brackets>(add_newline);
283 template <typename T, typename std::enable_if<!std::is_array<T>::value && !std::is_same<T, bool>::value, T>::type * =
nullptr>
284 void printbin(
const T data,
const bool add_newline =
true)
286 typedef const T data_as_array_type[1];
287 printbin<false>(*
reinterpret_cast<data_as_array_type *
>(&data), add_newline);
293 inline void printbin(
const bool data,
const bool add_newline =
true)
295 printbin(uint8_t(data), add_newline);
300 #endif // _BITPRINT_H_