1 #ifndef ZSERIO_BIT_BUFFER_H_INC 2 #define ZSERIO_BIT_BUFFER_H_INC 31 template <
typename ALLOC = std::allocator<u
int8_t>>
35 static_assert(std::is_same<uint8_t, typename ALLOC::value_type>::value,
36 "Allocator with uint8_t value_type is required!");
47 return m_buffer.get_allocator();
70 explicit BasicBitBuffer(
size_t bitSize,
const ALLOC& allocator = ALLOC());
115 explicit BasicBitBuffer(
const uint8_t* buffer,
size_t bitSize,
const ALLOC& allocator = ALLOC());
150 bool operator<(const BasicBitBuffer<ALLOC>& other)
const;
157 uint32_t hashCode()
const;
164 const uint8_t* getBuffer()
const;
171 uint8_t* getBuffer();
178 size_t getBitSize()
const;
187 size_t getByteSize()
const;
211 uint8_t getMaskedLastByte()
const;
217 template <
typename ALLOC>
219 m_buffer(ALLOC()), m_bitSize(0)
223 template <
typename ALLOC>
225 m_buffer(allocator), m_bitSize(0)
229 template <
typename ALLOC>
231 m_buffer((bitSize + 7) / 8, 0, allocator), m_bitSize(bitSize)
235 template <
typename ALLOC>
237 m_buffer(buffer.begin(), buffer.end(), allocator), m_bitSize(8 * buffer.size())
241 template <
typename ALLOC>
243 m_buffer(buffer.begin(), buffer.end(), allocator), m_bitSize(bitSize)
245 const size_t byteSize = (bitSize + 7) / 8;
246 if (buffer.
size() < byteSize)
249 " out of range for given span byte size " << buffer.
size() <<
"!";
253 template <
typename ALLOC>
255 m_buffer(std::move(buffer)), m_bitSize(8 * m_buffer.size())
259 template <
typename ALLOC>
261 m_buffer(std::move(buffer)), m_bitSize(bitSize)
263 const size_t byteSize = (bitSize + 7) / 8;
264 if (m_buffer.size() < byteSize)
267 " out of range for given vector byte size " << m_buffer.size() <<
"!";
271 template <
typename ALLOC>
273 m_buffer(buffer, buffer + (bitSize + 7) / 8, allocator), m_bitSize(bitSize)
277 template<
typename ALLOC>
279 m_buffer(other.m_buffer, allocator), m_bitSize(other.m_bitSize)
283 template<
typename ALLOC>
285 m_buffer(std::move(other.m_buffer), allocator), m_bitSize(other.m_bitSize)
289 template <
typename ALLOC>
294 if (m_bitSize != other.m_bitSize)
306 if (getMaskedLastByte() != other.getMaskedLastByte())
314 template <
typename ALLOC>
321 return byteSize2 != 0;
327 auto first1 = m_buffer.begin();
328 const auto last1 = first1 +
static_cast<difference_type
>(byteSize1 - 1);
329 auto first2 = other.m_buffer.begin();
330 const auto last2 = first2 +
static_cast<difference_type
>(byteSize2 - 1);
331 for (; (first1 != last1) && (first2 != last2); ++first1, ++first2)
333 if (*first1 < *first2)
335 if (*first2 < *first1)
339 const auto lastValue1 = first1 != last1 ? *first1 : getMaskedLastByte();
340 const auto lastValue2 = first2 != last2 ? *first2 : other.getMaskedLastByte();
341 if (lastValue1 < lastValue2)
343 if (lastValue2 < lastValue1)
346 return (first1 == last1) && (first2 != last2);
349 template <
typename ALLOC>
352 uint32_t result = ::zserio::HASH_SEED;
358 auto lastIt = m_buffer.begin() +
static_cast<int>(byteSize) - 1;
359 for (
auto it = m_buffer.begin(); it != lastIt; ++it)
368 template <
typename ALLOC>
371 return m_buffer.data();
374 template <
typename ALLOC>
377 return m_buffer.data();
380 template <
typename ALLOC>
386 template <
typename ALLOC>
389 return (m_bitSize + 7) / 8;
392 template <
typename ALLOC>
398 template <
typename ALLOC>
404 template <
typename ALLOC>
410 template <
typename ALLOC>
413 const size_t roundedByteSize = m_bitSize / 8;
414 const uint8_t lastByteBits =
static_cast<uint8_t
>(m_bitSize - 8 * roundedByteSize);
416 return (lastByteBits == 0) ? m_buffer[roundedByteSize - 1] :
417 (m_buffer[roundedByteSize] & (0xFFU << (8U - lastByteBits)));
431 template <
typename ALLOC>
434 return exception <<
"BitBuffer([...], " << bitBuffer.getBitSize() <<
")";
439 #endif // ifndef ZSERIO_BIT_BUFFER_H_INC
allocator_type get_allocator() const
const vector< uint8_t, ALLOC > & getBytes() const
const uint8_t * getBuffer() const
bool operator==(const BasicBitBuffer< ALLOC > &other) const
constexpr bool operator==(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
constexpr size_type size() const noexcept
uint32_t hashCode() const
std::vector< T, RebindAlloc< ALLOC, T >> vector
size_t getBitSize() const
size_t getByteSize() const
std::enable_if< std::is_integral< T >::value &&(sizeof(T)<=4), uint32_t >::type calcHashCode(uint32_t seedValue, T value)
Span< const uint8_t > getData() const
bool operator<(const BasicBitBuffer< ALLOC > &other) const