/// @file dpf/eval_point.hpp /// @brief /// @details /// @author Ryan Henry /// @author Christopher Jiang /// @copyright Copyright (c) 2019-2024 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license; /// see [LICENSE.md](@ref license) for details. #ifndef LIBDPF_INCLUDE_DPF_EVAL_POINT_HPP__ #define LIBDPF_INCLUDE_DPF_EVAL_POINT_HPP__ #include #include "hedley/hedley.h" #include #include #include "dpf/dpf_key.hpp" #include "dpf/eval_common.hpp" #include "dpf/eval_target.hpp" #include "dpf/path_memoizer.hpp" namespace dpf { namespace internal { template inline auto eval_point_interior(const DpfKey & dpf, InputT && x, PathMemoizer && path) { using dpf_type = DpfKey; auto level_index = detail::path_resume_for_level(path, dpf, x, dpf.depth); DPF_UNROLL_LOOP for (auto mask = dpf.msb_mask>>(level_index-1); level_index <= dpf.depth; ++level_index, mask>>=1) { bool bit = !!(mask & x); auto cw = dpf.correction_word(level_index-1, bit); path[level_index] = dpf_type::traverse_interior(path[level_index-1], cw, bit); } detail::path_note_filled_to(path, dpf.depth); } template inline auto eval_point_exterior(const DpfKey & dpf, PathMemoizer && path) { assert_not_wildcard_output(dpf); auto interior = path[dpf.depth]; return dpf.template traverse_exterior(interior); } template HEDLEY_ALWAYS_INLINE auto eval_point(const DpfKey & dpf, InputT && x, PathMemoizer && path) { utils::flip_msb_if_signed_integral(x); internal::eval_point_interior(dpf, x, path); return internal::eval_point_exterior(dpf, path); } } // namespace internal template , std::enable_if_t && !is_multilevel_key_v, bool> = true> HEDLEY_ALWAYS_INLINE auto eval_point(const DpfKey & dpf, InputT && x, PathMemoizer && path = PathMemoizer{}) { assert_not_wildcard_output(dpf); using output_type = typename DpfKey::concrete_output_type; auto tx = dpf.offset_x(x); return make_eval_dpf_output( internal::eval_point(dpf, tx, path), tx); } template , std::enable_if_t && !is_multilevel_key_v, bool> = true> HEDLEY_ALWAYS_INLINE auto eval_point(const DpfKey & dpf, InputT && x, PathMemoizer && path = PathMemoizer{}) { return std::make_tuple( *eval_point(dpf, x, path), *eval_point(dpf, x, path), *eval_point(dpf, x, path)...); } } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_EVAL_POINT_HPP__