12 #include <type_traits> 22 struct char_as_uint_trait {
23 static inline uint64_t conv(
const T& t) {
return t; }
26 struct char_as_uint_trait<char> {
27 static inline uint64_t conv(
const char& t) {
return uint8_t(t); }
31 inline uint64_t char_as_uint(
const T& t) {
32 return char_as_uint_trait<T>::conv(t);
50 for (
size_t i = 0; i < s.size() - 1; i++) {
53 ss << std::setw(indent) <<
uint((
unsigned char) s[i]) <<
", ";
55 ss << std::setw(indent) <<
uint((
unsigned char) s[s.size() - 1]);
72 if(length == 0)
return "[]";
75 for (
size_t i = 0; i < length - 1; ++i) {
90 std::stringstream out;
91 if (byte >= 32 && byte <= 127) {
92 out <<
"'" << char(byte) <<
"'";
111 char replacement =
'?') {
112 std::stringstream ss;
113 for (
size_t i = start; i < s.size(); i++) {
114 if (s[i] < 32 || s[i] > 127) {
129 std::stringstream ss;
135 for(
int i = 0; i < 64; i++) {
136 if (i > 0 && i % 8 == 0) {
139 std::cout << int((v >> (63 - i)) & 1);
161 while ((more =
bool(inp.get(c)))) {
162 if (c >=
'0' && c <=
'9') {
175 inline constexpr uint_fast8_t
bits_hi(uint64_t x) {
176 return x == 0 ? 0 : 64 - __builtin_clzll(x);
195 return n == 0 ? 1U :
bits_hi(n);
205 return (a / b) + ((a % b) > 0);
241 template<
typename int_t>
struct msbf;
245 template<>
struct msbf<uint8_t> {
248 static constexpr uint8_t
pos = 7;
252 template<>
struct msbf<uint16_t> {
255 static constexpr uint8_t
pos = 15;
259 template<>
struct msbf<uint32_t> {
262 static constexpr uint8_t
pos = 31;
266 template<>
struct msbf<uint64_t> {
269 static constexpr uint8_t
pos = 63;
283 std::vector<T>
cross(std::vector<std::vector<T>>&& vs,
284 std::function<T(T, T&)> f) {
286 if (remaining.size() == 0) {
290 std::vector<T> first = std::move(remaining[0]);
291 remaining.erase(remaining.begin());
293 auto next =
cross(std::move(remaining), f);
295 if (next.size() == 0) {
299 for (
auto& x : first) {
300 for (
auto& y : next) {
301 r.push_back(f(x, y));
312 inline std::vector<std::string>
split_lines(
const std::string& s) {
313 std::stringstream ss(s);
315 std::vector<std::string> ret;
317 while(std::getline(ss,to,
'\n')) {
331 std::stringstream ss(s);
333 std::stringstream ret;
336 while(std::getline(ss,to,
'\n')){
340 ret << std::setw(indent) <<
"" << to;
354 inline std::string
make_table(
const std::vector<std::string>& data,
356 bool draw_grid =
true) {
357 std::vector<size_t> widths;
358 std::vector<size_t> heights;
359 std::vector<std::vector<std::string>> data_lines;
362 for (
auto& elem : data) {
367 auto& lines = data_lines[data_lines.size() - 1];
369 for (
auto& line : lines) {
370 w = std::max(w, line.size());
377 heights.push_back(h);
380 std::vector<size_t> col_widths(cols, 0);
381 std::vector<size_t> row_heights(data.size() / cols, 0);
384 for (
size_t i = 0; i < data.size(); i++) {
388 col_widths[x] = std::max(col_widths[x], widths[i]);
389 row_heights[y] = std::max(row_heights[y], heights[i]);
393 for (
size_t i = 0; i < data.size(); i++) {
397 while (data_lines[i].size() < row_heights[y]) {
398 data_lines[i].push_back(
"");
401 for (
auto& line : data_lines[i]) {
402 size_t pad = col_widths[x] - line.size();
403 line.append(pad,
' ');
407 std::stringstream ret;
411 const char ROW =
'-';
412 const std::string COL =
" | ";
414 size_t total_width = 1;
415 for (
size_t i = 0; i < col_widths.size(); i++) {
416 total_width += col_widths[i] + 3;
420 ret << std::string(total_width, ROW) <<
"\n";
423 for (
size_t y = 0; y < data.size() / cols; y++) {
424 for (
size_t line_i = 0; line_i < row_heights[y]; line_i++ ) {
425 for (
size_t x = 0; x < cols; x++) {
426 if (draw_grid && x == 0) {
427 ret << COL.substr(1);
429 if (draw_grid && x != 0) {
432 ret << data_lines[x + y * cols][line_i];
433 if (draw_grid && x == cols - 1) {
434 ret << COL.substr(0, 2);
440 ret << std::string(total_width, ROW) <<
"\n";
447 #if defined(DEBUG) && defined(PARANOID) //functions that cost more than constant time to check 450 for(
size_t i = 0; i < n; ++i)
451 for(
size_t j = 0; j < n; ++j)
454 DCHECK_NE(p[i],p[j]) <<
"at positions " << i <<
" and " << j;
462 for(
size_t i = 0; i < n; ++i)
463 for(
size_t j = 0; j < n; ++j)
466 DCHECK_NE(p[i],p[j]) <<
"at positions " << i <<
" and " << j;
467 DCHECK_GE(p[i],offset);
468 DCHECK_LT(p[i],offset+n);
494 template<
class int_t>
497 int_t bit = 1ULL << (
sizeof(int_t)-2);
504 if (num >= res + bit) {
506 res = (res >> 1) + bit;
515 static inline size_t lz78_expected_number_of_remaining_elements(
const size_t z,
const size_t n,
const size_t remaining_characters) {
516 if(remaining_characters*2 < n ) {
517 return (z*remaining_characters) / (n - remaining_characters);
519 return remaining_characters*3/(
bits_for(remaining_characters));
527 DCHECK(other.m_is_not_moved) <<
"Trying to copy a already moved-from MoveGuard";
528 m_is_not_moved = other.m_is_not_moved;
531 DCHECK(other.m_is_not_moved) <<
"Trying to move a already moved-from MoveGuard";
532 m_is_not_moved = other.m_is_not_moved;
533 other.m_is_not_moved =
false;
537 return m_is_not_moved;
540 return !m_is_not_moved;
542 inline operator bool()
const {
543 return is_not_moved();
551 namespace portable_arithmetic_shift {
554 template <
typename T>
555 constexpr
auto builtin_shr(T value,
int amount) noexcept
556 -> decltype(value >> amount)
558 return value >> amount;
561 template <
typename T>
562 struct uses_arithmetic_shift : std::integral_constant<bool, builtin_shr(T(-1), 1) == -1> {};
564 template <
typename T =
int>
565 constexpr T shift_by_portable(T value,
int amount) noexcept
568 amount < 0 ? ~(~value >> -amount) : -(-value << amount) :
569 amount < 0 ? value >> -amount : value << amount;
572 template <
typename T =
int>
573 constexpr T shift_by_arithmetic(T value,
int amount) noexcept
576 return amount < 0 ? value >> -amount : value << amount;
581 template <
typename T =
int>
584 using namespace portable_arithmetic_shift;
586 return uses_arithmetic_shift<T>::value ? shift_by_arithmetic(value, amount) : shift_by_portable(value, amount);
Contains the text compression and encoding framework.
constexpr uint_fast8_t bits_for(size_t n)
Computes the number of bits required to store the given integer value.
std::string to_str(const T &v)
Represent a value as a string.
constexpr size_t idiv_ceil(size_t a, size_t b)
Performs an integer division with the result rounded up to the next integer.
std::string vec_to_debug_string(const T &s, size_t indent=0)
Builds the string representation of a vector of byte values, sorrounded by square brackets ([ and ])...
void debug_print_uint64_t(uint64_t v)
void assert_permutation(const T &, size_t)
MoveGuard(MoveGuard &&other)
uint64_t zero_or_next_power_of_two(uint64_t x)
std::string make_table(const std::vector< std::string > &data, size_t cols, bool draw_grid=true)
Renders the given dataset into an ASCII table.
constexpr uint_fast8_t bytes_for(size_t n)
Computes the number of bytes needed to store the given integer value.
Yields the position of the most significant bit for the template integer type.
constexpr T round_up_div(T x, T y)
Division with rounding up to the next integer.
void assert_permutation_offset(const T &, size_t, size_t)
constexpr uint_fast8_t bits_hi(uint64_t x)
Computes the highest set bit in an integer variable.
MoveGuard(const MoveGuard &other)
std::string byte_to_nice_ascii_char(uint64_t byte)
Converts a byte value into its ASCII representation sorrounded by single quotes (') or its string rep...
std::string indent_lines(const std::string &s, size_t indent)
Indents each line of a string (separated by \n) by the specified amount of spaces.
bool is_not_moved() const
std::string arr_to_debug_string(const T *s, size_t length)
Builds the string representation of an array of printable values, sorrounded by square brackets ([ an...
constexpr T shift_by(T value, int amount) noexcept
std::vector< T > cross(std::vector< std::vector< T >> &&vs, std::function< T(T, T &)> f)
Creates the cross product of a set of elements given a product function.
std::vector< std::string > split_lines(const std::string &s)
Splits the input string into lines (separated by \n).
std::string vec_as_lossy_string(const T &s, size_t start=0, char replacement='?')
Converts a vector of bytes into a readable ASCII string, substituting non-ASCII symbols.
bool parse_number_until_other(std::istream &inp, char &last, size_t &out)
Reads digits from the input stream (0 to 9) until a non-digit character is reached and parses them as...