17 #include <type_traits>
59 template <
typename Stream,
typename Block>
60 class bit_stream :
private std::reference_wrapper <Stream>
63 using buffer_type =
typename std::make_unsigned <type_extractor <Block>>::type;
64 enum{ block_bytes =
sizeof(buffer_type) };
65 enum{ block_bits = CHAR_BIT*block_bytes };
66 enum{ block_mask = static_cast <buffer_type> (~static_cast <buffer_type> (0)) };
67 enum{ byte_mask = static_cast <
unsigned char> (~static_cast <
unsigned char> (0)) };
70 template <std::
size_t N>
71 struct read_handler_fixed;
73 template <std::
size_t N, std::
size_t Buffer,
typename Enabler =
void>
74 struct read_bits_impl;
76 template <std::
size_t>
77 struct write_handler_fixed;
79 template <std::
size_t N, std::
size_t Buffer,
typename Enabler =
void>
80 struct write_bits_impl;
82 struct read_handler_dynamic;
83 struct write_handler_dynamic;
93 : std::reference_wrapper <Stream> (s)
100 template <std::
size_t N>
103 for (std::size_t i=0; i < N; ++i, ++s)
104 if (!read_bits <8> (*s))
113 bool read (
char* s, std::size_t n)
115 for (std::size_t i=0; i < n; ++i, ++s)
116 if (!read_bits <8> (*s))
125 template <std::
size_t N>
128 for (std::size_t i=0; i < N; ++i, ++s)
129 if (!write_bits <8> (*s))
138 bool write (
char const* s, std::size_t n)
140 for (std::size_t i=0; i < n; ++i, ++s)
141 if (!write_bits <8> (*s))
156 template <std::
size_t N,
typename T>
159 auto&
value = reinterpret_cast <
typename std::make_unsigned <T>::type&> (t);
160 return variadic_switch_return <case_list> (read_handler_fixed <N> {}, p_iInputBlockBits, *
this,
value);
172 template <
typename T>
175 auto&
value = reinterpret_cast <
typename std::make_unsigned <T>::type&> (t);
176 return variadic_switch_return <case_list> (read_handler_dynamic{}, p_iInputBlockBits, *
this,
value, n);
188 template <std::
size_t N,
typename T>
191 auto const&
value = reinterpret_cast <
typename std::make_unsigned <T>::type
const&> (t);
192 return variadic_switch_return <case_list> (write_handler_fixed <N> (), p_iOutputBlockBits, *
this,
value);
204 template <
typename T>
207 auto const&
value = reinterpret_cast <
typename std::make_unsigned <T>::type
const&> (t);
208 return variadic_switch_return <case_list> (write_handler_dynamic{}, p_iOutputBlockBits, *
this,
value, n);
220 if (p_iOutputBlockBits < block_bits)
223 if (!dispatch_write <Block> (
value, this->
get()))
227 p_iOutputBlockBits = block_bits;
234 buffer_type p_iInputBlock {0};
235 std::size_t p_iInputBlockBits {0};
237 buffer_type p_iOutputBlock {0};
238 std::size_t p_iOutputBlockBits {block_bits};
243 #include <framework/serializable/streams/bit_stream.inl>