61template <
typename Rewriter>
struct Mutator {
62 Mutator(Rewriter &rewriter) : rewriter_(rewriter) {}
64 template <
typename T,
typename U = llvm::remove_cvref_t<T>>
66 if constexpr (std::is_lvalue_reference_v<T>) {
69 return Mutate(std::move(x));
74 template <
typename T>
struct LambdaWithRvalueCapture {
75 LambdaWithRvalueCapture(Rewriter &r,
Expr<T> &&c)
76 : rewriter_(r), capture_(std::move(c)) {}
77 template <
typename S>
Expr<T> operator()(
const S &s) {
78 return rewriter_(std::move(capture_), s);
86 template <
typename T,
typename = std::enable_if_t<!is_operation_v<T>>>
87 T Mutate(T &&x)
const {
91 template <
typename D,
typename = std::enable_if_t<is_operation_v<D>>>
92 D Mutate(D &&op, std::make_index_sequence<D::operands> t = {})
const {
93 return MutateOp(std::move(op), t);
101 return Expr<T>(Mutate(std::move(s)));
107 return common::visit(
108 LambdaWithRvalueCapture<T>(rewriter_, std::move(n)), std::move(n.u));
111 template <
typename... Ts>
112 std::variant<Ts...> Mutate(std::variant<Ts...> &&u)
const {
113 return common::visit(
114 [
this](
auto &&s) {
return Mutate(std::move(s)); }, std::move(u));
117 template <
typename... Ts>
118 std::tuple<Ts...> Mutate(std::tuple<Ts...> &&t)
const {
119 return MutateTuple(std::move(t), std::index_sequence_for<Ts...>{});
122 template <
typename... Ts,
size_t... Is>
123 std::tuple<Ts...> MutateTuple(
124 std::tuple<Ts...> &&t, std::index_sequence<Is...>)
const {
125 return std::make_tuple(Mutate(std::move(std::get<Is>(t))...));
128 template <
typename D,
size_t... Is>
129 D MutateOp(D &&op, std::index_sequence<Is...>)
const {
130 return D(Mutate(std::move(op.template operand<Is>()))...);
133 template <
typename T,
size_t... Is>
136 op.ordering, Mutate(std::move(op.template operand<Is>()))...);
139 template <
int K,
size_t... Is>
143 op.isImaginaryPart, Mutate(std::move(op.template operand<Is>()))...);
146 template <
int K,
size_t... Is>
150 op.logicalOperator, Mutate(std::move(op.template operand<Is>()))...);