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:
Ryan Henry 2026-09-24 20:44:07 -06:00
parent 875f09fec1
commit 0d8a5a8131
97 changed files with 9212 additions and 1159 deletions

View file

@ -1,6 +1,11 @@
/// @file dpf/eval_unified.hpp
/// @brief Target-first eval surface for DPF / iDPF / DCF channels.
/// @details `eval_*(out<I>, …)` and `eval_*(cmp, …)` are the public API.
/// @details `eval_*(out<I>, …)` selects point-output slot `I`.
/// `eval_*(cmp, …)` selects the comparison channel. Memoizer and
/// buffer arguments match the classic overloads: a path memoizer
/// on `eval_point`, an output buffer then an interval memoizer on
/// `eval_interval`. `make_output_buffer(out<I>, key, from, to)` and
/// `make_output_buffer(cmp, key, n)` size the buffer for that channel.
/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors)
/// @license Released under a GNU General Public v2.0 (GPLv2) license.
@ -38,6 +43,7 @@ namespace detail
{
template <std::size_t I, std::size_t N, typename KeyT>
HEDLEY_NO_THROW
constexpr std::size_t resolved_out_prefix() noexcept
{
if constexpr (is_multilevel_key_v<KeyT>)
@ -91,6 +97,15 @@ auto eval_point(cmp_t, const KeyT & key, QueryT && x,
std::forward<PathMemoizer>(path));
}
template <std::size_t L, typename Beta = uint64_t, typename KeyT, typename QueryT,
typename PathMemoizer = basic_path_memoizer<KeyT>>
auto eval_point(cmp_prefix_t<L>, const KeyT & key, QueryT && x,
PathMemoizer && path = PathMemoizer{})
{
return detail::incr::eval_cmp_prefix_point_impl<L, Beta>(key,
std::forward<QueryT>(x), std::forward<PathMemoizer>(path));
}
// ---------------------------------------------------------------------------
// eval_interval(target, key, from, to [, buf [, memo]])
// ---------------------------------------------------------------------------
@ -388,11 +403,12 @@ auto eval_out_inner_product_impl(const KeyT & dpf, LaneT from, LaneT to,
utils::flip_msb_if_signed_integral(from);
utils::flip_msb_if_signed_integral(to);
integral_type from_node = utils::leaf_node_floor(
static_cast<integral_type>(to_int(from)), lg_opl);
integral_type to_node = utils::leaf_node_ceil_exclusive(
static_cast<integral_type>(to_int(to)), lg_opl);
const auto segs = utils::split_leaf_nodes(from_node, to_node, to_level);
const auto from_i = static_cast<integral_type>(to_int(from));
const auto to_i = static_cast<integral_type>(to_int(to));
integral_type from_node = utils::leaf_node_floor(from_i, lg_opl);
integral_type to_node = utils::leaf_node_ceil_exclusive(to_i, lg_opl);
const bool wraps = utils::interval_wraps(from_i, to_i, N);
const auto segs = utils::split_leaf_nodes(from_node, to_node, to_level, wraps);
ml_ip_accum<output_type, exterior_node> acc{};
std::size_t start = 0;
@ -437,15 +453,27 @@ Beta eval_cmp_inner_product_impl(const KeyT & dpf, LaneT from, LaneT to,
constexpr std::size_t stop =
KeyT::cmp_depth == 0 ? KeyT::depth : KeyT::cmp_depth;
detail::incr::cmp_full_interval_memo<KeyT, stop> memo{count};
const std::size_t levels = unwrap_party_key_t<KeyT>::cmp_block > 0
? unwrap_party_key_t<KeyT>::cmp_h : nbits;
detail::incr::eval_cmp_interval_impl_interior(dpf, a, cmp_exclusive_end(b),
nbits, memo);
nbits, memo, levels);
uint64_t dot = 0;
for (std::size_t i = 0; i < count; ++i)
{
const auto q = static_cast<integral>(a + static_cast<integral>(i));
const uint64_t raw =
detail::incr::eval_cmp_from_interval_memo(dpf, q, a, nbits, memo);
const uint64_t raw = [&] {
if constexpr (unwrap_party_key_t<KeyT>::cmp_block > 0)
{
return detail::blocked::eval_share_memo(dpf, q, a,
cmp_exclusive_end(b), memo);
}
else
{
return detail::incr::eval_cmp_from_interval_memo(
dpf, q, a, nbits, memo);
}
}();
const uint64_t wt = static_cast<uint64_t>(weights[i]) & mask;
dot = (dot + ((raw & mask) * wt)) & mask;
}