Annotate noexcept and constexpr with HEDLEY, and add interval containment, ChaCha, and the dyadic range tables.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
875f09fec1
commit
0d8a5a8131
97 changed files with 9212 additions and 1159 deletions
|
|
@ -64,7 +64,8 @@ template <typename T> inline constexpr bool is_at_v = is_at<T>::value;
|
|||
/// `OutBits` is the comparison output group width (bits of the β payload),
|
||||
/// so the value CWs / addend can be stored at group width instead of a full
|
||||
/// padded `uint64_t` per level.
|
||||
template <std::size_t Depth, std::size_t OutBits = 0, bool Wild = false>
|
||||
template <std::size_t Depth, std::size_t OutBits = 0, bool Wild = false,
|
||||
std::size_t BlockWidth = 0, bool Incremental = false>
|
||||
struct cmp_channel_tag
|
||||
{
|
||||
static constexpr std::size_t depth = Depth;
|
||||
|
|
@ -73,11 +74,17 @@ struct cmp_channel_tag
|
|||
/// after keygen. Concrete (non-wildcard) cmp keys keep `Wild == false`
|
||||
/// so their layout / type name is unchanged.
|
||||
static constexpr bool wild = Wild;
|
||||
/// 0 keeps the per-level path-sum. `B >= 1` selects blocked checkpoints
|
||||
/// of target width `B`.
|
||||
static constexpr std::size_t block_width = BlockWidth;
|
||||
/// Save a final correction at every depth (`idcf`).
|
||||
static constexpr bool incremental = Incremental;
|
||||
};
|
||||
|
||||
template <typename T> struct is_cmp_channel_tag : std::false_type {};
|
||||
template <std::size_t Depth, std::size_t OutBits, bool Wild>
|
||||
struct is_cmp_channel_tag<cmp_channel_tag<Depth, OutBits, Wild>>
|
||||
template <std::size_t Depth, std::size_t OutBits, bool Wild, std::size_t Block,
|
||||
bool Incremental>
|
||||
struct is_cmp_channel_tag<cmp_channel_tag<Depth, OutBits, Wild, Block, Incremental>>
|
||||
: std::true_type {};
|
||||
template <typename T>
|
||||
inline constexpr bool is_cmp_channel_tag_v =
|
||||
|
|
@ -107,6 +114,28 @@ struct is_placed<placed<N, O>> : std::true_type {};
|
|||
template <typename T>
|
||||
inline constexpr bool is_placed_v = is_placed<std::decay_t<T>>::value;
|
||||
|
||||
/// Heavy-hitters incremental point function: one payload per prefix length.
|
||||
/// `levels[i]` is the bit length of slot `i`.
|
||||
template <typename LevelSeq, typename ...Betas>
|
||||
struct idpf_pack;
|
||||
|
||||
template <std::size_t ...Levels, typename ...Betas>
|
||||
struct idpf_pack<std::index_sequence<Levels...>, Betas...>
|
||||
{
|
||||
static constexpr bool is_idpf = true;
|
||||
static constexpr std::size_t n = sizeof...(Levels);
|
||||
static constexpr std::array<std::size_t, n == 0 ? 1 : n> levels{
|
||||
Levels...};
|
||||
std::tuple<Betas...> values;
|
||||
};
|
||||
|
||||
template <typename T> struct is_idpf : std::false_type {};
|
||||
template <std::size_t ...Levels, typename ...Betas>
|
||||
struct is_idpf<idpf_pack<std::index_sequence<Levels...>, Betas...>>
|
||||
: std::true_type {};
|
||||
template <typename T>
|
||||
inline constexpr bool is_idpf_v = is_idpf<std::decay_t<T>>::value;
|
||||
|
||||
template <typename NodeT, typename OutputT>
|
||||
inline constexpr std::size_t out_bits_v =
|
||||
utils::bitlength_of_output_v<concrete_type_t<OutputT>, NodeT>;
|
||||
|
|
@ -385,6 +414,8 @@ struct normalize_one
|
|||
static constexpr std::size_t cmp_depth = 0;
|
||||
static constexpr std::size_t cmp_out_bits = 0;
|
||||
static constexpr bool cmp_wild = false;
|
||||
static constexpr std::size_t cmp_block = 0;
|
||||
static constexpr bool cmp_idcf = false;
|
||||
};
|
||||
template <std::size_t BitLen, std::size_t N, typename T>
|
||||
struct normalize_one<BitLen, placed<N, T>>
|
||||
|
|
@ -393,14 +424,20 @@ struct normalize_one<BitLen, placed<N, T>>
|
|||
static constexpr std::size_t cmp_depth = 0;
|
||||
static constexpr std::size_t cmp_out_bits = 0;
|
||||
static constexpr bool cmp_wild = false;
|
||||
static constexpr std::size_t cmp_block = 0;
|
||||
static constexpr bool cmp_idcf = false;
|
||||
};
|
||||
template <std::size_t BitLen, std::size_t Depth, std::size_t OutBits, bool Wild>
|
||||
struct normalize_one<BitLen, cmp_channel_tag<Depth, OutBits, Wild>>
|
||||
template <std::size_t BitLen, std::size_t Depth, std::size_t OutBits, bool Wild,
|
||||
std::size_t Block, bool Incremental>
|
||||
struct normalize_one<BitLen,
|
||||
cmp_channel_tag<Depth, OutBits, Wild, Block, Incremental>>
|
||||
{
|
||||
using placed_tuple = std::tuple<>;
|
||||
static constexpr std::size_t cmp_depth = Depth;
|
||||
static constexpr std::size_t cmp_out_bits = OutBits;
|
||||
static constexpr bool cmp_wild = Wild;
|
||||
static constexpr std::size_t cmp_block = Block;
|
||||
static constexpr bool cmp_idcf = Incremental;
|
||||
};
|
||||
|
||||
template <std::size_t BitLen, typename ...Elems>
|
||||
|
|
@ -419,6 +456,10 @@ struct normalize_pack
|
|||
// wildcard flag (false when there is no cmp channel).
|
||||
static constexpr bool cmp_wild =
|
||||
(false || ... || normalize_one<BitLen, Elems>::cmp_wild);
|
||||
static constexpr std::size_t cmp_block =
|
||||
(std::size_t{0} + ... + normalize_one<BitLen, Elems>::cmp_block);
|
||||
static constexpr bool cmp_idcf =
|
||||
(false || ... || normalize_one<BitLen, Elems>::cmp_idcf);
|
||||
};
|
||||
|
||||
template <std::size_t BitLen>
|
||||
|
|
@ -428,6 +469,8 @@ struct normalize_pack<BitLen>
|
|||
static constexpr std::size_t cmp_depth = 0;
|
||||
static constexpr std::size_t cmp_out_bits = 0;
|
||||
static constexpr bool cmp_wild = false;
|
||||
static constexpr std::size_t cmp_block = 0;
|
||||
static constexpr bool cmp_idcf = false;
|
||||
};
|
||||
|
||||
/// True iff the pack is "classic-shaped": every element is a bare output (no
|
||||
|
|
@ -439,6 +482,32 @@ inline constexpr bool is_classic_pack_v =
|
|||
} // namespace incr
|
||||
} // namespace detail
|
||||
|
||||
/// Sparse heavy-hitters IDPF. Slot `i` is the point function on prefix
|
||||
/// `Levels[i]`, evaluated with `out<i>`.
|
||||
template <std::size_t ...Levels, typename ...Betas>
|
||||
auto idpf_at(Betas ...betas)
|
||||
{
|
||||
static_assert(sizeof...(Levels) == sizeof...(Betas),
|
||||
"idpf_at: one payload per prefix length");
|
||||
return detail::incr::idpf_pack<std::index_sequence<Levels...>,
|
||||
std::decay_t<Betas>...>{
|
||||
std::tuple<std::decay_t<Betas>...>{std::move(betas)...}};
|
||||
}
|
||||
|
||||
template <std::size_t ...I, typename ...Betas>
|
||||
auto idpf_from_seq(std::index_sequence<I...>, Betas ...betas)
|
||||
{
|
||||
return idpf_at<(I + 1)...>(std::move(betas)...);
|
||||
}
|
||||
|
||||
/// Consecutive prefixes of length 1, 2, …, `sizeof...(Betas)`.
|
||||
template <typename ...Betas>
|
||||
auto idpf(Betas ...betas)
|
||||
{
|
||||
return idpf_from_seq(std::make_index_sequence<sizeof...(Betas)>{},
|
||||
std::move(betas)...);
|
||||
}
|
||||
|
||||
} // namespace dpf
|
||||
|
||||
#endif // LIBDPF_INCLUDE_DPF_PLACEMENT_HPP__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue