23template<
typename E, std::
size_t Dim,
typename BoundValue>
29 static constexpr std::size_t
dim_v = Dim;
31 static constexpr std::size_t
arity_v = (E::arity_v > 0) ? (E::arity_v - 1) : 0;
39 [[nodiscard]]
constexpr value_type eval(std::span<value_type const> args)
const {
40 std::vector<value_type> full_args;
43 std::size_t args_idx = 0;
46 full_args.push_back(get_bound_value());
47 }
else if (args_idx < args.size()) {
48 full_args.push_back(args[args_idx++]);
54 return expr.eval(std::span<value_type const>{full_args});
58 return eval(std::span<value_type const>{});
61 [[nodiscard]] [[deprecated(
"use eval() instead")]]
66 [[nodiscard]] [[deprecated(
"use eval() instead")]]
72 template<std::
size_t DerivDim>
74 constexpr std::size_t original_dim = (DerivDim >= Dim) ? (DerivDim + 1) : DerivDim;
75 auto d_expr =
expr.template derivative<original_dim>();
80 std::ostringstream oss;
81 oss <<
"(bind " << Dim <<
" " << get_bound_value() <<
" " <<
expr.to_string() <<
")";
86 [[nodiscard]]
constexpr value_type get_bound_value()
const {
87 if constexpr (std::is_arithmetic_v<BoundValue>) {
96template<std::
size_t Dim,
typename E,
typename T>
97 requires is_expr_node_v<E>
98[[nodiscard]]
constexpr auto bind(E expr, T value) {
99 static_assert(Dim < E::arity_v || E::arity_v == 0,
100 "Cannot bind a dimension that doesn't exist in the expression");
102 using VT =
typename E::value_type;
104 if constexpr (std::is_arithmetic_v<T>) {
112template<std::size_t Dim, std::size_t... Dims,
typename E,
typename T,
typename... Ts>
113 requires is_expr_node_v<E>
114[[nodiscard]]
constexpr auto bind_all(E expr, T value, Ts... values) {
115 auto bound_once = bind<Dim>(expr, value);
116 if constexpr (
sizeof...(Dims) == 0) {
119 return bind_all<Dims...>(bound_once, values...);
124template<
typename E,
typename T>
125 requires is_expr_node_v<E>
126[[nodiscard]]
constexpr auto partial(E expr, T value) {
127 return bind<0>(expr, value);
131template<
typename E,
typename T>
132 requires is_expr_node_v<E>
134 constexpr std::size_t last_dim = (E::arity_v > 0) ? (E::arity_v - 1) : 0;
135 return bind<last_dim>(expr, value);
Expression layer for composable calculus.
constexpr auto bind_all(E expr, T value, Ts... values)
constexpr auto partial_right(E expr, T value)
constexpr auto bind(E expr, T value)
constexpr auto partial(E expr, T value)
static constexpr std::size_t original_arity_v
constexpr value_type eval() const
constexpr value_type evaluate() const
typename E::value_type value_type
std::string to_string() const
constexpr value_type evaluate(std::span< value_type const > args) const
static constexpr std::size_t arity_v
constexpr value_type eval(std::span< value_type const > args) const
static constexpr std::size_t dim_v
constexpr auto derivative() const
constexpr BoundExpr(E e, BoundValue v) noexcept