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
|
|
@ -1,6 +1,13 @@
|
|||
/// @file dpf/interval_memoizer.hpp
|
||||
/// @brief
|
||||
/// @details
|
||||
/// @brief Workspaces for an inclusive interval of DPF leaves.
|
||||
/// @details `basic_interval_memoizer` keeps two levels of the interval.
|
||||
/// `full_tree_interval_memoizer` keeps every level. Size either one
|
||||
/// for the widest interval you will evaluate; a wider interval
|
||||
/// throws `std::length_error`. The same key and the same endpoints
|
||||
/// leave the final interior level in place.
|
||||
///
|
||||
/// Factories unwrap `party_key`. Pass the memoizer as a mutable
|
||||
/// lvalue to `eval_interval` or `eval_full`.
|
||||
/// @author Ryan Henry <ryan.henry@ucalgary.ca>
|
||||
/// @author Christopher Jiang <christopher.jiang@ucalgary.ca>
|
||||
/// @copyright Copyright (c) 2019-2024 Ryan Henry and [others](@ref authors)
|
||||
|
|
@ -55,10 +62,13 @@ struct interval_memoizer_base
|
|||
|
||||
// level 0 should access the root
|
||||
// level goes up to (and including) depth
|
||||
HEDLEY_NO_THROW
|
||||
virtual return_type operator[](std::size_t) const noexcept = 0;
|
||||
|
||||
// iterators should access most recently completed level
|
||||
HEDLEY_NO_THROW
|
||||
virtual return_type begin() const noexcept = 0;
|
||||
HEDLEY_NO_THROW
|
||||
virtual return_type end() const noexcept = 0;
|
||||
|
||||
virtual std::size_t assign_interval(const dpf_type & dpf, integral_type new_from, integral_type new_to)
|
||||
|
|
@ -151,6 +161,8 @@ struct interval_memoizer_base
|
|||
std::optional<integral_type> to_;
|
||||
};
|
||||
|
||||
/// Two-level workspace for one interval. This is what
|
||||
/// `eval_interval(key, from, to)` allocates when you omit the memoizer.
|
||||
template <typename DpfKey,
|
||||
typename Allocator = aligned_allocator<
|
||||
typename interval_memoizer_key_t<DpfKey>::interior_node>>
|
||||
|
|
@ -229,6 +241,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop)
|
|||
unique_ptr buf;
|
||||
};
|
||||
|
||||
/// Every level of the interval. `retains_all_levels` is true.
|
||||
template <typename DpfKey,
|
||||
typename Allocator = aligned_allocator<
|
||||
typename interval_memoizer_key_t<DpfKey>::interior_node>>
|
||||
|
|
@ -392,6 +405,7 @@ struct basic_interval_memoizer_at
|
|||
- utils::shift_right(from_node, offset) + 1;
|
||||
}
|
||||
|
||||
HEDLEY_NO_THROW
|
||||
return_type operator[](std::size_t level) const noexcept
|
||||
{
|
||||
bool b = (depth ^ level) & 1;
|
||||
|
|
@ -420,9 +434,6 @@ auto make_interval_memoizer(InputT from, InputT to)
|
|||
{
|
||||
using dpf_type = DpfKey;
|
||||
|
||||
utils::flip_msb_if_signed_integral(from);
|
||||
utils::flip_msb_if_signed_integral(to);
|
||||
|
||||
std::size_t nodes_in_interval = utils::get_leafnodes_in_output_interval<dpf_type>(from, to);
|
||||
|
||||
return MemoizerT(nodes_in_interval);
|
||||
|
|
@ -430,6 +441,10 @@ auto make_interval_memoizer(InputT from, InputT to)
|
|||
|
||||
} // namespace detail
|
||||
|
||||
/// Two-level workspace sized for the closed interval `[from, to]`.
|
||||
/// @param from Inclusive start, in the key's input domain.
|
||||
/// @param to Inclusive end. `to` is at least `from` in that domain.
|
||||
/// @snippet evaluation/memoizers.cpp interval-memoizer
|
||||
template <typename DpfKey,
|
||||
typename InputT>
|
||||
inline auto make_basic_interval_memoizer(InputT from, InputT to)
|
||||
|
|
@ -448,6 +463,7 @@ inline auto make_basic_interval_memoizer(const DpfKey &, InputT from, InputT to)
|
|||
return make_basic_interval_memoizer<DpfKey>(from, to);
|
||||
}
|
||||
|
||||
/// `make_basic_interval_memoizer` sized for the whole input domain.
|
||||
template <typename DpfKey>
|
||||
inline auto make_basic_full_memoizer()
|
||||
{
|
||||
|
|
@ -464,6 +480,7 @@ inline auto make_basic_full_memoizer(const DpfKey &)
|
|||
return make_basic_full_memoizer<DpfKey>();
|
||||
}
|
||||
|
||||
/// Full-tree workspace sized for the closed interval `[from, to]`.
|
||||
template <typename DpfKey,
|
||||
typename InputT>
|
||||
inline auto make_full_tree_interval_memoizer(InputT from, InputT to)
|
||||
|
|
@ -482,6 +499,7 @@ inline auto make_full_tree_interval_memoizer(const DpfKey &, InputT from, InputT
|
|||
return make_full_tree_interval_memoizer<DpfKey>(from, to);
|
||||
}
|
||||
|
||||
/// `make_full_tree_interval_memoizer` sized for the whole input domain.
|
||||
template <typename DpfKey>
|
||||
inline auto make_full_tree_full_memoizer()
|
||||
{
|
||||
|
|
@ -521,11 +539,13 @@ inline auto make_basic_interval_memoizer(InputT from, InputT to)
|
|||
utils::flip_msb_if_signed_integral(from);
|
||||
utils::flip_msb_if_signed_integral(to);
|
||||
|
||||
const integral_type from_node = utils::leaf_node_floor(
|
||||
static_cast<integral_type>(to_int(from)), lg);
|
||||
const integral_type to_node = utils::leaf_node_ceil_exclusive(
|
||||
static_cast<integral_type>(to_int(to)), lg);
|
||||
const auto segs = utils::split_leaf_nodes(from_node, to_node, stop);
|
||||
const auto from_i = static_cast<integral_type>(to_int(from));
|
||||
const auto to_i = static_cast<integral_type>(to_int(to));
|
||||
const integral_type from_node = utils::leaf_node_floor(from_i, lg);
|
||||
const integral_type to_node = utils::leaf_node_ceil_exclusive(to_i, lg);
|
||||
const bool wraps = utils::interval_wraps(from_i, to_i,
|
||||
utils::bitlength_of_v<InputT>);
|
||||
const auto segs = utils::split_leaf_nodes(from_node, to_node, stop, wraps);
|
||||
return basic_interval_memoizer_at<DpfKey, stop>(segs.total);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue