OGLplus  (0.59.0) a C++ wrapper for rendering APIs

bit_density.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_BIT_DENSITY_HPP
10 #define EAGINE_BIT_DENSITY_HPP
11 
12 #include "assert.hpp"
13 #include "types.hpp"
14 #include "valid_if/decl.hpp"
15 #include <climits>
16 
17 namespace eagine {
18 //------------------------------------------------------------------------------
19 // type at least twice the size of byte
20 using double_byte = std::conditional_t<
21  (CHAR_BIT > 8),
22  uint_fast16_t,
23  std::conditional_t<(CHAR_BIT > 16), uint_fast32_t, uint_fast64_t>>;
24 //------------------------------------------------------------------------------
25 static constexpr auto byte_bits() noexcept {
26  return span_size_t(CHAR_BIT);
27 }
28 //------------------------------------------------------------------------------
29 static constexpr auto
30 dissolved_bits_length(span_size_t original_length, span_size_t bits) noexcept
31  -> span_size_t {
32  return EAGINE_CONSTEXPR_ASSERT(
33  (bits >= 1) and (bits <= byte_bits()),
34  (((original_length * byte_bits()) / bits) +
35  (((original_length * byte_bits()) % bits) ? 1 : 0)));
36 }
37 //------------------------------------------------------------------------------
38 static constexpr auto
39 concentrated_bits_length(span_size_t original_length, span_size_t bits) noexcept
40  -> span_size_t {
41  return EAGINE_CONSTEXPR_ASSERT(
42  (bits >= 1) and (bits <= byte_bits()),
43  (((original_length * bits) / byte_bits()) +
44  (((original_length * bits) % byte_bits()) ? 1 : 0)));
45 }
46 //------------------------------------------------------------------------------
47 template <typename Getter, typename Putter>
48 static inline auto
49 do_dissolve_bits(Getter get, Putter put, span_size_t bits) noexcept -> bool {
50 
51  EAGINE_ASSERT(bits >= 1);
52  EAGINE_ASSERT(bits <= byte_bits());
53 
54  span_size_t r = 0;
55  double_byte w = 0U;
56  const auto m = byte((1U << bits) - 1U); // NOLINT(hicpp-signed-bitwise)
57 
58  auto push = [&]() -> bool {
59  while(r >= bits) {
60  if(!put(byte(w >> double_byte(r - bits)) & m)) {
61  return false;
62  }
63  r -= bits;
64  }
65  return true;
66  };
67 
68  while(true) {
69  if(r < bits) {
70  if(auto src = get()) {
71  w <<= byte_bits(); // NOLINT(hicpp-signed-bitwise)
72  w |= double_byte(extract(src));
73  r += byte_bits();
74  } else {
75  break;
76  }
77  }
78  if(!push()) {
79  return false;
80  }
81  }
82 
83  if(r > 0) {
84  EAGINE_ASSERT(r < bits);
85  if(!put(byte(w << double_byte(bits - r)) & m)) {
86  return false;
87  }
88  }
89  return true;
90 }
91 //------------------------------------------------------------------------------
92 template <typename Getter, typename Putter>
93 static inline auto
94 do_concentrate_bits(Getter get, Putter put, span_size_t bits) noexcept -> bool {
95  EAGINE_ASSERT(bits >= 1);
96  EAGINE_ASSERT(bits <= byte_bits());
97 
98  span_size_t r = 0;
99  double_byte w = 0U;
100  const double_byte m = (1U << bits) - 1U; // NOLINT(hicpp-signed-bitwise)
101 
102  bool done = false;
103 
104  while(!done) {
105  while(r < byte_bits()) {
106  if(auto src = get()) {
107  w <<= bits; // NOLINT(hicpp-signed-bitwise)
108  // NOLINTNEXTLINE(hicpp-signed-bitwise)
109  w = (w & ~m) | (double_byte(extract(src)) & m);
110  r += bits;
111  } else {
112  done = true;
113  break;
114  }
115  }
116  if(r >= byte_bits()) {
117  if(!put(byte(w >> double_byte(r - byte_bits())))) {
118  return false;
119  }
120  r -= byte_bits();
121  }
122  }
123  return true;
124 }
125 //------------------------------------------------------------------------------
126 } // namespace eagine
127 
128 #endif // EAGINE_BIT_DENSITY_HPP
std::ptrdiff_t span_size_t
Signed span size type used by eagine.
Definition: types.hpp:36
Common code is placed in this namespace.
Definition: eagine.hpp:21
static constexpr auto extract(api_result_value< Result, api_result_validity::never > &) noexcept -> Result &
Overload of extract for api_result_value.
Definition: c_api_wrap.hpp:270
unsigned char byte
Byte type alias.
Definition: types.hpp:24

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).