-
Notifications
You must be signed in to change notification settings - Fork 50
/
PatriciaTreeUtil.h
91 lines (69 loc) · 2.33 KB
/
PatriciaTreeUtil.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <cstdint>
#include <type_traits>
#include <utility>
#include <sparta/PatriciaTreeKeyTrait.h>
namespace sparta {
namespace pt_util {
template <typename Key>
struct Codec {
using IntegerType = typename PatriciaTreeKeyTrait<Key>::IntegerType;
static_assert(std::is_unsigned_v<IntegerType>,
"IntegerType is not an unsigned arithmetic type");
static_assert(sizeof(IntegerType) == sizeof(Key),
"IntegerType and Key must have the same size");
static_assert(std::alignment_of<IntegerType>::value ==
std::alignment_of<Key>::value,
"IntegerType and Key must have the same alignment");
static const IntegerType& encode(const Key& key) {
return reinterpret_cast<const IntegerType&>(key);
}
// To correctly conform to the forward iterator concept, these must
// return reinterpreted references to storage - not copies.
template <typename T>
static std::enable_if_t<!std::is_lvalue_reference_v<T>> decode(T&&) = delete;
static const Key& decode(const IntegerType& integer_key) {
return reinterpret_cast<const Key&>(integer_key);
}
template <typename Value>
static const std::pair<Key, Value>& decode(
const std::pair<IntegerType, Value>& pair) {
return reinterpret_cast<const std::pair<Key, Value>&>(pair);
}
};
template <typename IntegerType>
inline bool is_zero_bit(IntegerType k, IntegerType m) {
return (k & m) == 0;
}
template <typename IntegerType>
inline IntegerType get_lowest_bit(IntegerType x) {
return x & (~x + 1);
}
template <typename IntegerType>
inline IntegerType get_branching_bit(IntegerType prefix0, IntegerType prefix1) {
return get_lowest_bit(prefix0 ^ prefix1);
}
template <typename IntegerType>
IntegerType mask(IntegerType k, IntegerType m) {
return k & (m - 1);
}
template <typename IntegerType>
IntegerType match_prefix(IntegerType k, IntegerType p, IntegerType m) {
return mask(k, m) == p;
}
template <typename T>
std::enable_if_t<!std::is_pointer_v<T>, const T&> deref(const T& x) {
return x;
}
template <typename T>
const T& deref(const T* x) {
return *x;
}
} // namespace pt_util
} // namespace sparta