yfast 0.6.1
Loading...
Searching...
No Matches
bit_extractor.h
1#ifndef _YFAST_INTERNAL_BIT_EXTRACTOR_H
2#define _YFAST_INTERNAL_BIT_EXTRACTOR_H
3
4#include <cstddef>
5#include <string>
6#include <type_traits>
7#include <vector>
8
9#include <yfast/internal/hash.h>
10
11namespace yfast::internal {
12
13template <typename Key, typename = void>
15
16template <typename Key>
17class BitExtractor<Key, std::enable_if_t<std::is_integral_v<Key>>> {
18public:
19 typedef Key ShiftResult;
20
21 static bool extract_bit(Key key, unsigned int n) { return key & (1 << n); }
22 static Key shift(Key key, unsigned int n) { return key >> n; }
23};
24
25template <>
26class BitExtractor<std::vector<std::byte>> {
27public:
28 typedef std::vector<std::byte> ShiftResult;
29
30 static bool extract_bit(const std::byte* data, std::size_t size, unsigned int n) {
31 const auto s = n / 8;
32 if (size <= s) {
33 return false;
34 }
35 const auto r = n % 8;
36 const auto mask = std::byte{1} << r;
37 return (data[size - s - 1] & mask) != std::byte{0};
38 }
39
40 static bool extract_bit(const std::vector<std::byte>& key, unsigned int n) {
41 return extract_bit(key.data(), key.size(), n);
42 }
43
44 // [l | r] [l | r] [l | r]
45 // [l] [r | l] [r | l]
46 static std::vector<std::byte> shift(const std::byte* data, std::size_t size, unsigned int n) {
47 const auto s = n / 8;
48 if (size <= s) {
49 return {};
50 }
51
52 const auto shifted_size = size - s;
53 std::vector<std::byte> shifted(shifted_size);
54 const auto r = n % 8;
55 if (r == 0) {
56 std::ranges::copy(data, data + shifted_size, shifted.begin());
57 return shifted;
58 }
59
60 const auto l = 8 - r;
61 std::transform(data, data + shifted_size, shifted.begin(), [r] (std::byte b) { return b >> r; });
62 for (int i = 1; i < shifted_size; ++i) {
63 shifted[i] |= data[i - 1] << l;
64 }
65 return shifted;
66 }
67
68 static std::vector<std::byte> shift(const std::vector<std::byte>& key, unsigned int n) {
69 return shift(key.data(), key.size(), n);
70 }
71};
72
73template <>
74class BitExtractor<std::string> {
75public:
76 typedef std::vector<std::byte> ShiftResult;
77
78 static bool extract_bit(const std::string& key, unsigned int n) {
79 const auto data = reinterpret_cast<const std::byte*>(key.data());
80 return BitExtractor<std::vector<std::byte>>::extract_bit(data, key.size(), n);
81 }
82
83 static std::vector<std::byte> shift(const std::string& key, unsigned int n) {
84 const auto data = reinterpret_cast<const std::byte*>(key.data());
85 return BitExtractor<std::vector<std::byte>>::shift(data, key.size(), n);
86 }
87};
88
89}
90
91#endif
Definition bit_extractor.h:14