From bf9f94870e2555773ea8dc22af744fa6477171f7 Mon Sep 17 00:00:00 2001 From: Yuya Asano <64895419+sukeya@users.noreply.github.com> Date: Sun, 23 Nov 2025 14:23:03 +0900 Subject: [PATCH] Remove expression template. --- include/mvPolynomial/expression.hpp | 439 ---------------------------- 1 file changed, 439 deletions(-) delete mode 100644 include/mvPolynomial/expression.hpp diff --git a/include/mvPolynomial/expression.hpp b/include/mvPolynomial/expression.hpp deleted file mode 100644 index 7adb029..0000000 --- a/include/mvPolynomial/expression.hpp +++ /dev/null @@ -1,439 +0,0 @@ -#ifndef _MVPOLYNOMIAL_POLYNOMIAL_EXPRESSION_HPP_ -#define _MVPOLYNOMIAL_POLYNOMIAL_EXPRESSION_HPP_ - -#include -#include -#include -#include -#include -#include - -namespace myPolynomial { -template -bool is_const_ref_v = std::is_const_v && std::is_reference_v; - -template -bool is_rvalue_v = std::is_rvalue_reference_v && (!std::is_const_v); - -template -struct FilterRvalue; - -template -struct FilterRvalue { - using type = T; - - static constexpr bool is_rvalue = true; -}; - -template -struct FilterRvalue { - using type = const T&; - - static constexpr bool is_rvalue = false; -}; - -template -requires is_const_ref_v || is_rvalue_v -class RefWrapper final { - using FilterResult = FilterRvalue; - - public: - using Domain = typename T::Domain; - using Range = typename T::Range; - - using Storage = FilterResult::value; - - static constexpr bool is_rvalue = FilterResult::is_rvalue; - - RefWrapper() = delete; - - RefWrapper(const RefWrapper&) = default; - RefWrapper(RefWrapper&&) = default; - RefWrapper& operator=(const RefWrapper&) = default; - RefWrapper& operator=(RefWrapper&&) = default; - ~RefWrapper() = default; - - RefWrapper(T&& t) : t_(std::forward(t)) {} - - Range operator()(const Domain& x) const { return t_(x); } - - const Storage& read() const - requires(!is_rvalue) - { - return t_; - } - - const Storage& read() const - requires(is_rvalue) - { - return t_; - } - - const Storage& move() && - requires(!is_rvalue) - { - return t_; - } - - Storage move() && - requires(is_rvalue) - { - return std::move(t_); - } - - private: - Storage t_; -}; - -// L and R may be either const& or &&. -template -requires(is_const_ref_v || is_rvalue_v) && (is_const_ref_v || is_rvalue_v) -class BinaryExpr final { - using LRef = RefWrapper; - using RRef = RefWrapper; - - public: - static_assert(std::is_same_v, "Domain mismatch!"); - static_assert(std::is_same_v, "Range mismatch!"); - - using Domain = typename L::Domain; - using Range = typename L::Range; - - static constexpr bool is_l_rvalue = LRef::is_rvalue; - static constexpr bool is_r_rvalue = RRef::is_rvalue; - - BinaryExpr() = delete; - - BinaryExpr(const BinaryExpr&) = default; - BinaryExpr(BinaryExpr&&) = default; - BinaryExpr& operator=(const BinaryExpr&) = default; - BinaryExpr& operator=(BinaryExpr&&) = default; - ~BinaryExpr() = default; - - BinaryExpr(L&& l, R&& r) : l_(std::forward(l)), r_(std::forward(r)) {} - - // Calculate x of this - Range operator()(const Domain& x) const { return Op::Apply(l_(x), r_(x)); } - - const auto& read_l() const { return l_.read(); } - - const auto& read_r() const { return r_.read(); } - - auto move_l() - requires(is_l_rvalue) - { - return std::move(l_).move(); - } - - decltype(auto) move_l() - requires(!is_l_rvalue) - { - return std::move(l_).move(); - } - - auto move_r() - requires(is_r_rvalue) - { - return std::move(r_).move(); - } - - decltype(auto) move_r() - requires(!is_r_rvalue) - { - return std::move(r_).move(); - } - - private: - LRef l_; - RRef r_; -}; - -struct Plus { - template - requires(!std::is_floating_point_v) - static R Apply(R&& l, R&& r) { - return std::forward(l) + std::forward(r); - } - - template - requires std::is_floating_point_v - static R Apply(R l, R r) { - return l + r; - } -}; - -struct Minus { - template - requires(!std::is_floating_point_v) - static R Apply(R&& l, R&& r) { - return std::forward(l) - std::forward(r); - } - - template - requires std::is_floating_point_v - static R Apply(R l, R r) { - return l - r; - } -}; - -struct Multiply { - template - requires(!std::is_floating_point_v) - static R Apply(R&& l, R&& r) { - return std::forward(l) * std::forward(r); - } - - template - requires std::is_floating_point_v - static R Apply(R l, R r) { - return l * r; - } -}; - -// F and G may be either const& or &&. -template -requires(is_const_ref_v || is_rvalue_v) && (is_const_ref_v || is_rvalue_v) -class Composition final { - using FRef = RefWrapper; - using GRef = RefWrapper; - - public: - static_assert(std::is_same_v, "Cannot composite!"); - - using Domain = typename G::Domain; - using Range = typename F::Range; - - static constexpr bool is_outer_rvalue = FRef::is_rvalue; - static constexpr bool is_inner_rvalue = GRef::is_rvalue; - - Composition() = delete; - - Composition(const Composition&) = default; - Composition(Composition&&) = default; - Composition& operator=(const Composition&) = default; - Composition& operator=(Composition&&) = default; - ~Composition() = default; - - Composition(F&& f, G&& g) : f_(std::forward(f)), g_(std::forward(g)) {} - - Range operator()(const Domain& x) const { return f_(g_(x)); } - - const auto& read_outer() const { return f_.read(); } - - const auto& read_inner() const { return g_.read(); } - - auto move_outer() - requires(is_outer_rvalue) - { - return std::move(f_).move(); - } - - decltype(auto) move_outer() - requires(!is_outer_rvalue) - { - return std::move(f_).move(); - } - - auto move_inner() - requires(is_inner_rvalue) - { - return std::move(g_).move(); - } - - decltype(auto) move_inner() - requires(!is_inner_rvalue) - { - return std::move(g_).move(); - } - - private: - FRef f_; - GRef g_; -}; - -template -requires is_const_ref_v || is_rvalue_v -class Power { - using FRef = RefWrapper; - - public: - using Domain = typename F::Domain; - using Range = typename F::Range; - - static constexpr bool is_base_rvalue = FRef::is_rvalue; - - Power() = delete; - - Power(const Power&) = default; - Power(Power&&) = default; - Power& operator=(const Power&) = default; - Power& operator=(Power&&) = default; - ~Power() = default; - - Power(F&& f, int exp) : f_(std::forward(f)), exp_(exp) { - if (exp < 0) { - throw std::invalid_argument("Exponent must be non-negative!"); - } - } - - Range operator()(const Domain& x) const - requires(std::is_floating_point_v) - { - return std::pow(f_(x), exp_); - } - Range operator()(const Domain& x) const - requires(!std::is_floating_point_v) - { - return Pow(f_(x), exp_); - } - - const auto& read_base() const { return f_.read(); } - int read_expo() const { return exp_; } - - auto move_base() - requires(is_base_rvalue) - { - return std::move(f_).move(); - } - - decltype(auto) move_base() - requires(!is_base_rvalue) - { - return std::move(f_).move(); - } - - private: - FRef f_; - int exp_; -}; - -template -auto D(int axis, BinaryExpr&& expr) { - auto d_l = D(axis, expr.move_l()); - auto d_r = D(axis, expr.move_r()); - return BinaryExpr{std::move(d_l), std::move(d_r)}; -} - -template -auto D(int axis, const BinaryExpr& expr) { - auto d_l = D(axis, expr.read_l()); - auto d_r = D(axis, expr.read_r()); - return BinaryExpr{std::move(d_l), std::move(d_r)}; -} - -template -auto D(int axis, BinaryExpr&& expr) { - auto d_l = D(axis, expr.move_l()); - auto d_r = D(axis, expr.move_r()); - return BinaryExpr{std::move(d_l), std::move(d_r)}; -} - -template -auto D(int axis, const BinaryExpr& expr) { - auto d_l = D(axis, expr.read_l()); - auto d_r = D(axis, expr.read_r()); - return BinaryExpr{std::move(d_l), std::move(d_r)}; -} - -template -auto DMultiplyImpl(L&& l, R&& r, DL&& d_l, DR&& d_r) { - auto l_prod = - BinaryExpr{std::move(d_l), std::forward(r)}; - auto r_prod = - BinaryExpr{std::forward(l), std::move(d_r)}; - return BinaryExpr{ - std::move(l_prod), - std::move(r_prod) - }; -} - -template -auto D(int axis, BinaryExpr&& expr) { - auto d_l = D(axis, expr.read_l()); - auto d_r = D(axis, expr.read_r()); - return DMultiplyImpl(expr.move_l(), expr.move_r(), std::move(d_l), std::move(d_r)); -} - -template -auto D(int axis, const BinaryExpr& expr) { - auto d_l = D(axis, expr.read_l()); - auto d_r = D(axis, expr.read_r()); - return DMultiplyImpl(expr.read_l(), expr.read_r(), std::move(d_l), std::move(d_r)); -} - -template -auto D(int axis, Composition&& comp) { - auto d_f = D(axis, comp.move_outer()); - const auto& g = comp.read_inner(); - auto d_g = D(axis, g); - return BinaryExpr, Multiply, decltype(d_g)&&>{ - Composition{std::move(d_f), comp.move_inner()}, - std::move(d_g) - }; -} - -template -auto D(int axis, const Composition& comp) { - auto d_f = D(axis, comp.read_outer()); - const auto& g = comp.read_inner(); - auto d_g = D(axis, g); - return BinaryExpr, Multiply, decltype(d_g)&&>{ - Composition{std::move(d_f), g}, - std::move(d_g) - }; -} - -template -auto D(int axis, Power&& pow_f) { - auto d_f = D(axis, pow_f.read_base()); - return BinaryExpr&&>, Multiply, decltype(d_f)&&>{ - BinaryExpr&&>{ - pow_f.read_expo(), - Power{pow_f.move_base(), pow_f.read_expo() - 1}, - }, - std::move(d_f) - }; -} - -template -auto D(int axis, const Power& pow_f) { - auto d_f = D(axis, pow_f.read_base()); - return BinaryExpr&>, Multiply, decltype(d_f)&&>{ - BinaryExpr&>{ - pow_f.read_expo(), - Power{pow_f.read_base(), pow_f.read_expo() - 1}, - }, - std::move(d_f) - }; -} - -template -auto S(std::size_t axis, B&& begin, E&& end, BinaryExpr&& expr) { - auto s_l = S(axis, std::forward(begin), std::forward(end), expr.move_l()); - auto s_r = S(axis, std::forward(begin), std::forward(end), expr.move_r()); - return BinaryExpr{std::move(s_l), std::move(s_r)}; -} - -template -auto S(std::size_t axis, B&& begin, E&& end, const BinaryExpr& expr) { - auto s_l = S(axis, std::forward(begin), std::forward(end), expr.read_l()); - auto s_r = S(axis, std::forward(begin), std::forward(end), expr.read_r()); - return BinaryExpr{std::move(s_l), std::move(s_r)}; -} - -template -auto S(std::size_t axis, B&& begin, E&& end, BinaryExpr&& expr) { - auto s_l = S(axis, std::forward(begin), std::forward(end), expr.move_l()); - auto s_r = S(axis, std::forward(begin), std::forward(end), expr.move_r()); - return BinaryExpr{std::move(s_l), std::move(s_r)}; -} - -template -auto S(std::size_t axis, B&& begin, E&& end, const BinaryExpr& expr) { - auto s_l = S(axis, std::forward(begin), std::forward(end), expr.read_l()); - auto s_r = S(axis, std::forward(begin), std::forward(end), expr.read_r()); - return BinaryExpr{std::move(s_l), std::move(s_r)}; -} -} // namespace myPolynomial - -#endif