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/path_memoizer.hpp
|
||||
/// @brief
|
||||
/// @details
|
||||
/// @brief Workspaces that resume a root-to-leaf DPF walk.
|
||||
/// @details `basic_path_memoizer` keeps one interior node per level. The next
|
||||
/// `eval_point` recomputes the suffix after the common prefix with
|
||||
/// the previous input. `nonmemoizing_path_memoizer` keeps a single
|
||||
/// node and starts at the root on every call.
|
||||
///
|
||||
/// Pass a mutable lvalue to `eval_point`. The factories unwrap
|
||||
/// `party_key`, so a memoizer built from either party's type
|
||||
/// accepts both parties. A different root restarts the path.
|
||||
/// @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)
|
||||
|
|
@ -44,13 +51,21 @@ struct path_memoizer_base
|
|||
using return_type = ReturnT;
|
||||
using iterator_type = return_type;
|
||||
|
||||
HEDLEY_NO_THROW
|
||||
virtual std::size_t assign_x(const dpf_type &, input_type) noexcept = 0;
|
||||
HEDLEY_NO_THROW
|
||||
virtual node_type & operator[](std::size_t) noexcept = 0;
|
||||
|
||||
HEDLEY_NO_THROW
|
||||
virtual return_type begin() const noexcept = 0;
|
||||
HEDLEY_NO_THROW
|
||||
virtual return_type end() const noexcept = 0;
|
||||
};
|
||||
|
||||
/// One interior node per level. `assign_x` returns the first level that the
|
||||
/// next walk must recompute. `filled_to` is the deepest level already
|
||||
/// written for the current input. Callers pass this object to `eval_point`;
|
||||
/// they do not call `assign_x` themselves.
|
||||
template <typename DpfKey>
|
||||
struct alignas(alignof(typename path_memoizer_key_t<DpfKey>::interior_node))
|
||||
basic_path_memoizer final
|
||||
|
|
@ -69,12 +84,15 @@ HEDLEY_PRAGMA(GCC diagnostic pop)
|
|||
|
||||
basic_path_memoizer()
|
||||
: dpf_{std::nullopt}, x_{std::nullopt}, filled_to_{0} { }
|
||||
HEDLEY_NO_THROW
|
||||
basic_path_memoizer(basic_path_memoizer &&) noexcept = default;
|
||||
basic_path_memoizer(const basic_path_memoizer &) = default;
|
||||
HEDLEY_NO_THROW
|
||||
basic_path_memoizer & operator=(basic_path_memoizer &&) noexcept = default;
|
||||
basic_path_memoizer & operator=(const basic_path_memoizer &) = default;
|
||||
~basic_path_memoizer() = default;
|
||||
|
||||
HEDLEY_NO_THROW
|
||||
std::size_t assign_x(const dpf_type & dpf, input_type new_x) noexcept override
|
||||
{
|
||||
static constexpr auto clz_xor = utils::countl_zero_symmetric_difference<input_type>{};
|
||||
|
|
@ -100,11 +118,13 @@ HEDLEY_PRAGMA(GCC diagnostic pop)
|
|||
return 1;
|
||||
}
|
||||
|
||||
HEDLEY_NO_THROW
|
||||
node_type & operator[](std::size_t i) noexcept override
|
||||
{
|
||||
return arr_[i];
|
||||
}
|
||||
|
||||
HEDLEY_NO_THROW
|
||||
return_type begin() const noexcept override
|
||||
{
|
||||
if (x_.has_value() == true)
|
||||
|
|
@ -117,14 +137,17 @@ HEDLEY_PRAGMA(GCC diagnostic pop)
|
|||
}
|
||||
}
|
||||
|
||||
HEDLEY_NO_THROW
|
||||
return_type end() const noexcept override
|
||||
{
|
||||
return std::addressof(arr_[depth+1]);
|
||||
}
|
||||
|
||||
/// Inclusive high-water: `arr_[0..filled_to_]` are valid for the current x.
|
||||
HEDLEY_NO_THROW
|
||||
std::size_t filled_to() const noexcept { return filled_to_; }
|
||||
|
||||
HEDLEY_NO_THROW
|
||||
void note_filled(std::size_t level) noexcept
|
||||
{
|
||||
if (level > filled_to_)
|
||||
|
|
@ -143,6 +166,7 @@ HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
|||
HEDLEY_PRAGMA(GCC diagnostic pop)
|
||||
};
|
||||
|
||||
/// A single interior node. Every `assign_x` restarts at the root.
|
||||
template <typename DpfKey>
|
||||
struct nonmemoizing_path_memoizer final
|
||||
: public path_memoizer_base<path_memoizer_key_t<DpfKey>>
|
||||
|
|
@ -159,8 +183,10 @@ HEDLEY_PRAGMA(GCC diagnostic pop)
|
|||
|
||||
nonmemoizing_path_memoizer()
|
||||
: dpf_{std::nullopt} { }
|
||||
HEDLEY_NO_THROW
|
||||
nonmemoizing_path_memoizer(nonmemoizing_path_memoizer &&) noexcept = default;
|
||||
nonmemoizing_path_memoizer(const nonmemoizing_path_memoizer &) = default;
|
||||
HEDLEY_NO_THROW
|
||||
nonmemoizing_path_memoizer & operator=(nonmemoizing_path_memoizer &&) noexcept = default;
|
||||
nonmemoizing_path_memoizer & operator=(const nonmemoizing_path_memoizer &) = default;
|
||||
~nonmemoizing_path_memoizer() = default;
|
||||
|
|
@ -186,6 +212,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop)
|
|||
return std::addressof(v);
|
||||
}
|
||||
|
||||
HEDLEY_NO_THROW
|
||||
return_type end() const noexcept override
|
||||
{
|
||||
return std::addressof(v) + 1;
|
||||
|
|
@ -260,6 +287,9 @@ void ensure_level(const DpfKey & dpf, typename DpfKey::input_type x,
|
|||
|
||||
} // namespace detail
|
||||
|
||||
/// Path workspace for `DpfKey`. A `party_key` argument is unwrapped, and the
|
||||
/// result accepts both parties.
|
||||
/// @snippet evaluation/memoizers.cpp path-memoizer
|
||||
template <typename DpfKey>
|
||||
auto make_basic_path_memoizer()
|
||||
{
|
||||
|
|
@ -272,6 +302,7 @@ auto make_basic_path_memoizer(const DpfKey &)
|
|||
return make_basic_path_memoizer<DpfKey>();
|
||||
}
|
||||
|
||||
/// Single-node path workspace. Suitable for one query.
|
||||
template <typename DpfKey>
|
||||
auto make_nonmemoizing_path_memoizer()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue