156 lines
5.9 KiB
C++
156 lines
5.9 KiB
C++
|
|
/// @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<I>, …)` 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 <type_traits>
|
||
|
|
#include <utility>
|
||
|
|
|
||
|
|
#include "dpf/eval_target.hpp"
|
||
|
|
|
||
|
|
namespace dpf
|
||
|
|
{
|
||
|
|
|
||
|
|
template <typename T>
|
||
|
|
inline constexpr bool peel_key_v =
|
||
|
|
has_embedded_dpf_key_v<std::decay_t<T>>
|
||
|
|
&& !owns_protocol_eval_v<std::decay_t<T>>;
|
||
|
|
|
||
|
|
template <typename T>
|
||
|
|
inline constexpr bool peel_tag_key_v =
|
||
|
|
has_embedded_dpf_key_v<std::decay_t<T>>;
|
||
|
|
|
||
|
|
#define LIBDPF_PEEL_KEY_FIRST(fn) \
|
||
|
|
template <std::size_t I = 0, \
|
||
|
|
typename KeyT, \
|
||
|
|
typename... Args, \
|
||
|
|
std::enable_if_t<peel_key_v<KeyT>, int> = 0> \
|
||
|
|
decltype(auto) fn(const KeyT & key, Args &&... args) \
|
||
|
|
{ \
|
||
|
|
return fn<I>(key.dpf_key, std::forward<Args>(args)...); \
|
||
|
|
}
|
||
|
|
|
||
|
|
#define LIBDPF_PEEL_TAG_FIRST(fn) \
|
||
|
|
template <typename Tag, \
|
||
|
|
typename KeyT, \
|
||
|
|
typename... Args, \
|
||
|
|
std::enable_if_t<peel_tag_key_v<KeyT> \
|
||
|
|
&& is_eval_channel_tag_v<std::decay_t<Tag>>, int> = 0> \
|
||
|
|
decltype(auto) fn(Tag tag, const KeyT & key, Args &&... args) \
|
||
|
|
{ \
|
||
|
|
return fn(tag, key.dpf_key, std::forward<Args>(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 <typename KeyT,
|
||
|
|
typename... Args,
|
||
|
|
std::enable_if_t<peel_key_v<KeyT>, int> = 0>
|
||
|
|
decltype(auto) eval_sequence_xor(const KeyT & key, Args &&... args)
|
||
|
|
{
|
||
|
|
return eval_sequence_xor(key.dpf_key, std::forward<Args>(args)...);
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename KeyT,
|
||
|
|
typename... Args,
|
||
|
|
std::enable_if_t<peel_key_v<KeyT>, int> = 0>
|
||
|
|
decltype(auto) prove_cmp_interval(const KeyT & key, Args &&... args)
|
||
|
|
{
|
||
|
|
return prove_cmp_interval(key.dpf_key, std::forward<Args>(args)...);
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename KeyT,
|
||
|
|
typename... Args,
|
||
|
|
std::enable_if_t<peel_key_v<KeyT>, int> = 0>
|
||
|
|
decltype(auto) prove_cmp_full(const KeyT & key, Args &&... args)
|
||
|
|
{
|
||
|
|
return prove_cmp_full(key.dpf_key, std::forward<Args>(args)...);
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename KeyT,
|
||
|
|
typename... Args,
|
||
|
|
std::enable_if_t<peel_key_v<KeyT>, int> = 0>
|
||
|
|
decltype(auto) prove_cmp_sequence(const KeyT & key, Args &&... args)
|
||
|
|
{
|
||
|
|
return prove_cmp_sequence(key.dpf_key, std::forward<Args>(args)...);
|
||
|
|
}
|
||
|
|
|
||
|
|
template <std::size_t I = 0,
|
||
|
|
typename Buffer,
|
||
|
|
typename KeyT,
|
||
|
|
typename... Args,
|
||
|
|
std::enable_if_t<peel_key_v<KeyT>, int> = 0>
|
||
|
|
void eval_full_add_into(Buffer & buf, const KeyT & key, Args &&... args)
|
||
|
|
{
|
||
|
|
eval_full_add_into<I>(buf, key.dpf_key, std::forward<Args>(args)...);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// @brief Row-wise and column inner products keep the tag in front of the key.
|
||
|
|
template <typename Tag,
|
||
|
|
typename KeyT,
|
||
|
|
typename... Args,
|
||
|
|
std::enable_if_t<peel_tag_key_v<KeyT>
|
||
|
|
&& (std::is_same_v<std::decay_t<Tag>, paired_t>
|
||
|
|
|| std::is_same_v<std::decay_t<Tag>, 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>(args)...);
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Tag,
|
||
|
|
typename KeyT,
|
||
|
|
typename... Args,
|
||
|
|
std::enable_if_t<peel_tag_key_v<KeyT>
|
||
|
|
&& (std::is_same_v<std::decay_t<Tag>, paired_t>
|
||
|
|
|| std::is_same_v<std::decay_t<Tag>, 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>(args)...);
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Tag,
|
||
|
|
typename KeyT,
|
||
|
|
typename... Args,
|
||
|
|
std::enable_if_t<peel_tag_key_v<KeyT>
|
||
|
|
&& (std::is_same_v<std::decay_t<Tag>, paired_t>
|
||
|
|
|| std::is_same_v<std::decay_t<Tag>, 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>(args)...);
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace dpf
|
||
|
|
|
||
|
|
#endif // LIBDPF_INCLUDE_DPF_EVAL_PEEL_HPP__
|