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,14 @@
/// @file dpf/output_buffer.hpp
/// @brief
/// @details
/// @brief Move-only storage for shares written by multi-point evaluation.
/// @details Slot type follows the key. A `party_key` leaf buffer holds
/// `subtractive_share`s; a comparison buffer holds
/// `additive_share`s. `bit`, `twobit`, and `nyble` slots are packed.
/// Trivially default-constructible slots are left uninitialized
/// because evaluation overwrites every slot it is responsible for.
///
/// `eval_interval` and recipe `eval_sequence` take the buffer by
/// non-const reference. The returned iterable refers into it.
/// @snippet evaluation/output_buffers.cpp output-buffer
/// @author Ryan Henry <ryan.henry@ucalgary.ca>
/// @copyright Copyright (c) 2019-2024 Ryan Henry and [others](@ref authors)
/// @license Released under a GNU General Public v2.0 (GPLv2) license;
@ -9,6 +17,8 @@
#ifndef LIBDPF_INCLUDE_DPF_OUTPUT_BUFFER_HPP__
#define LIBDPF_INCLUDE_DPF_OUTPUT_BUFFER_HPP__
#include "hedley/hedley.h"
#include <cstddef>
#include <algorithm>
#include <tuple>
@ -77,9 +87,12 @@ class output_buffer_allocator : public aligned_allocator<T, Alignment>
using other = output_buffer_allocator<U, Alignment>;
};
HEDLEY_NO_THROW
output_buffer_allocator() noexcept = default;
HEDLEY_NO_THROW
output_buffer_allocator(const output_buffer_allocator &) noexcept = default;
template <typename U>
HEDLEY_NO_THROW
output_buffer_allocator(const output_buffer_allocator<U, Alignment> &) noexcept {}
template <typename U>
@ -100,6 +113,7 @@ class output_buffer_allocator : public aligned_allocator<T, Alignment>
}
template <typename U>
HEDLEY_NO_THROW
void destroy(U * p) noexcept
{
if constexpr (!std::is_trivially_destructible_v<U>)
@ -110,6 +124,7 @@ class output_buffer_allocator : public aligned_allocator<T, Alignment>
};
template <typename T, std::size_t A, typename U, std::size_t B>
HEDLEY_NO_THROW
constexpr bool operator==(const output_buffer_allocator<T, A> &,
const output_buffer_allocator<U, B> &) noexcept
{
@ -117,12 +132,15 @@ constexpr bool operator==(const output_buffer_allocator<T, A> &,
}
template <typename T, std::size_t A, typename U, std::size_t B>
HEDLEY_NO_THROW
constexpr bool operator!=(const output_buffer_allocator<T, A> & lhs,
const output_buffer_allocator<U, B> & rhs) noexcept
{
return !(lhs == rhs);
}
/// Move-only vector of `T`. Copy construction and copy assignment are
/// deleted. `at`, `operator[]`, `data`, iterators, and `size` are public.
template <typename T,
std::size_t Alignment = utils::max_align_v>
class output_buffer final
@ -135,13 +153,17 @@ class output_buffer final
using iterator = typename vector::iterator;
using const_iterator = typename vector::const_iterator;
using size_type = typename vector::size_type;
HEDLEY_NO_THROW
output_buffer() noexcept = default;
explicit output_buffer(size_type size) : vector(size) { }
HEDLEY_NO_THROW
output_buffer(output_buffer &&) noexcept = default;
output_buffer(const output_buffer &) = delete;
HEDLEY_NO_THROW
output_buffer & operator=(output_buffer &&) noexcept = default;
output_buffer & operator=(const output_buffer &) = delete;
~output_buffer() = default;
HEDLEY_NO_THROW
~output_buffer() noexcept = default;
// "selectively public" inheritance
using vector::at;
@ -161,11 +183,14 @@ class output_buffer<dpf::bit> : public dpf::dynamic_bit_array<>
using size_type = typename dpf::dynamic_bit_array<>::size_type;
public:
explicit output_buffer(size_type size) : dynamic_bit_array(size) { }
HEDLEY_NO_THROW
output_buffer(output_buffer &&) noexcept = default;
output_buffer(const output_buffer &) = delete;
HEDLEY_NO_THROW
output_buffer & operator=(output_buffer &&) noexcept = default;
output_buffer & operator=(const output_buffer &) = delete;
~output_buffer() = default;
HEDLEY_NO_THROW
~output_buffer() noexcept = default;
};
template <>
@ -175,11 +200,14 @@ class output_buffer<dpf::twobit> : public dpf::dynamic_packed_array<dpf::twobit>
public:
using size_type = typename base::size_type;
explicit output_buffer(size_type size) : base(size) { }
HEDLEY_NO_THROW
output_buffer(output_buffer &&) noexcept = default;
output_buffer(const output_buffer &) = delete;
HEDLEY_NO_THROW
output_buffer & operator=(output_buffer &&) noexcept = default;
output_buffer & operator=(const output_buffer &) = delete;
~output_buffer() = default;
HEDLEY_NO_THROW
~output_buffer() noexcept = default;
};
template <>
@ -189,11 +217,14 @@ class output_buffer<dpf::nyble> : public dpf::dynamic_packed_array<dpf::nyble>
public:
using size_type = typename base::size_type;
explicit output_buffer(size_type size) : base(size) { }
HEDLEY_NO_THROW
output_buffer(output_buffer &&) noexcept = default;
output_buffer(const output_buffer &) = delete;
HEDLEY_NO_THROW
output_buffer & operator=(output_buffer &&) noexcept = default;
output_buffer & operator=(const output_buffer &) = delete;
~output_buffer() = default;
HEDLEY_NO_THROW
~output_buffer() noexcept = default;
};
#define LIBDPF_PACKED_SHARE_BUFFER(LANE, PARTY) \
@ -205,11 +236,14 @@ class output_buffer<subtractive_share<LANE, PARTY>>
public: \
using size_type = typename base::size_type; \
explicit output_buffer(size_type size) : base(size) {} \
HEDLEY_NO_THROW \
output_buffer(output_buffer &&) noexcept = default; \
output_buffer(const output_buffer &) = delete; \
HEDLEY_NO_THROW \
output_buffer & operator=(output_buffer &&) noexcept = default; \
output_buffer & operator=(const output_buffer &) = delete; \
~output_buffer() = default; \
HEDLEY_NO_THROW \
~output_buffer() noexcept = default; \
};
LIBDPF_PACKED_SHARE_BUFFER(dpf::twobit, 0);
@ -232,12 +266,14 @@ class output_buffer<subtractive_share<dpf::bit, PARTY>>
output_buffer(const output_buffer &) = delete; \
output_buffer & operator=(output_buffer &&) noexcept = default; \
output_buffer & operator=(const output_buffer &) = delete; \
~output_buffer() = default; \
~output_buffer() noexcept = default; \
};
LIBDPF_BIT_SHARE_BUFFER(0);
LIBDPF_BIT_SHARE_BUFFER(1);
#undef LIBDPF_BIT_SHARE_BUFFER
/// Buffer sized for the closed interval `[from, to]` of output `I`.
/// On a `party_key`, elements are subtractive shares of that output.
template <typename DpfKey,
std::size_t I = 0,
typename InputT>
@ -247,9 +283,6 @@ auto make_output_buffer_for_interval(InputT from, InputT to)
using output_type = typename DpfKey::concrete_output_type<I>;
using buffer_elem = leaf_buffer_elem_t<DpfKey, output_type>;
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 dpf::output_buffer<buffer_elem>(nodes_in_interval*dpf_type::outputs_per_leaf);
}
@ -285,6 +318,7 @@ inline auto make_output_buffer_for_interval(const DpfKey &, InputT from, InputT
return make_output_buffer_for_interval<DpfKey, I0, I1, Is...>(from, to);
}
/// Buffer sized for every input of output `I`.
template <typename DpfKey,
std::size_t I = 0>
auto make_output_buffer_for_full()