/// @file dpf/eval_peel.hpp /// @brief Eval overloads that accept a wrapper and evaluate its `dpf_key`. /// @details Include this after the eval headers. A call passes through while /// the argument has a public `dpf_key` member and is not itself a /// DPF key. `dpf3` / `dpf3_cmp` / `dpf3_ic` keep their key-first /// protocol overloads; `eval_*(cmp, …)` and `eval_*(out, …)` still /// peel those wrappers down to the inner DPF key. /// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license. #ifndef LIBDPF_INCLUDE_DPF_EVAL_PEEL_HPP__ #define LIBDPF_INCLUDE_DPF_EVAL_PEEL_HPP__ #include #include #include "dpf/eval_target.hpp" namespace dpf { template inline constexpr bool peel_key_v = has_embedded_dpf_key_v> && !owns_protocol_eval_v>; template inline constexpr bool peel_tag_key_v = has_embedded_dpf_key_v>; #define LIBDPF_PEEL_KEY_FIRST(fn) \ template , int> = 0> \ decltype(auto) fn(const KeyT & key, Args &&... args) \ { \ return fn(key.dpf_key, std::forward(args)...); \ } #define LIBDPF_PEEL_TAG_FIRST(fn) \ template \ && is_eval_channel_tag_v>, int> = 0> \ decltype(auto) fn(Tag tag, const KeyT & key, Args &&... args) \ { \ return fn(tag, key.dpf_key, std::forward(args)...); \ } LIBDPF_PEEL_KEY_FIRST(eval_point) LIBDPF_PEEL_KEY_FIRST(eval_interval) LIBDPF_PEEL_KEY_FIRST(eval_full) LIBDPF_PEEL_KEY_FIRST(eval_sequence) LIBDPF_PEEL_KEY_FIRST(eval_inner_product) LIBDPF_PEEL_KEY_FIRST(eval_full_inner_product) LIBDPF_PEEL_KEY_FIRST(eval_sequence_inner_product) LIBDPF_PEEL_TAG_FIRST(eval_point) LIBDPF_PEEL_TAG_FIRST(eval_interval) LIBDPF_PEEL_TAG_FIRST(eval_full) LIBDPF_PEEL_TAG_FIRST(eval_sequence) LIBDPF_PEEL_TAG_FIRST(eval_sequence_breadth_first) LIBDPF_PEEL_TAG_FIRST(eval_inner_product) LIBDPF_PEEL_TAG_FIRST(eval_full_inner_product) LIBDPF_PEEL_TAG_FIRST(make_output_buffer) LIBDPF_PEEL_TAG_FIRST(make_sequence_recipe) LIBDPF_PEEL_TAG_FIRST(eval_prefixes) LIBDPF_PEEL_TAG_FIRST(eval_prefix_inner_product) #undef LIBDPF_PEEL_KEY_FIRST #undef LIBDPF_PEEL_TAG_FIRST template , int> = 0> decltype(auto) eval_sequence_xor(const KeyT & key, Args &&... args) { return eval_sequence_xor(key.dpf_key, std::forward(args)...); } template , int> = 0> decltype(auto) prove_cmp_interval(const KeyT & key, Args &&... args) { return prove_cmp_interval(key.dpf_key, std::forward(args)...); } template , int> = 0> decltype(auto) prove_cmp_full(const KeyT & key, Args &&... args) { return prove_cmp_full(key.dpf_key, std::forward(args)...); } template , int> = 0> decltype(auto) prove_cmp_sequence(const KeyT & key, Args &&... args) { return prove_cmp_sequence(key.dpf_key, std::forward(args)...); } template , int> = 0> void eval_full_add_into(Buffer & buf, const KeyT & key, Args &&... args) { eval_full_add_into(buf, key.dpf_key, std::forward(args)...); } /// @brief Row-wise and column inner products keep the tag in front of the key. template && (std::is_same_v, paired_t> || std::is_same_v, columns_t>), int> = 0> decltype(auto) eval_inner_product(Tag tag, const KeyT & key, Args &&... args) { return eval_inner_product(tag, key.dpf_key, std::forward(args)...); } template && (std::is_same_v, paired_t> || std::is_same_v, columns_t>), int> = 0> decltype(auto) eval_full_inner_product(Tag tag, const KeyT & key, Args &&... args) { return eval_full_inner_product(tag, key.dpf_key, std::forward(args)...); } template && (std::is_same_v, paired_t> || std::is_same_v, columns_t>), int> = 0> decltype(auto) eval_sequence_inner_product(Tag tag, const KeyT & key, Args &&... args) { return eval_sequence_inner_product(tag, key.dpf_key, std::forward(args)...); } } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_EVAL_PEEL_HPP__