codac 1.5.6
Loading...
Searching...
No Matches
codac2_ExprBase.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include <map>
13#include <memory>
14#include <cassert>
15#include <utility>
16#include "codac2_Domain.h"
17#include "codac2_Index.h"
18
19namespace codac2
20{
21 class ExprBase;
22 class VarBase;
23
24 class ExprID
25 {
26 public:
27
28 ExprID();
29 Index id() const;
30 bool operator==(const ExprID& i) const;
31 bool operator<(const ExprID& i) const;
32
33 protected:
34
35 const Index _id;
36 static Index _id_counter;
37 };
38
39 class ExprBase : public std::enable_shared_from_this<ExprBase>
40 {
41 public:
42
43 ExprBase();
44 virtual std::shared_ptr<ExprBase> copy() const = 0;
45 virtual void replace_expr(const ExprID& old_expr_id, const std::shared_ptr<ExprBase>& new_expr) = 0;
46
47 const ExprID& unique_id() const;
48 bool operator==(const ExprBase& e) const;
49 virtual ~ExprBase() = default;
50
51 protected:
52
53 const ExprID _unique_id;
54 };
55
56 template<typename... X>
57 class OperationExprBase
58 {
59 public:
60
61 OperationExprBase(std::shared_ptr<X>... x)
62 : _x(std::make_tuple((x)...))
63 { }
64
65 OperationExprBase(const OperationExprBase<X...>& e)
66 : _x(e._x)
67 {
68 std::apply(
69 [](auto &&... x)
70 {
71 ((x = _copy(x)), ...);
72 }, _x);
73 }
74
75 void replace_expr(const ExprID& old_expr_id, const std::shared_ptr<ExprBase>& new_expr)
76 {
77 std::apply(
78 [old_expr_id,new_expr](auto &&... x)
79 {
80 (__replace_single_expr(x,old_expr_id,new_expr), ...);
81 }, _x);
82 }
83
84 protected:
85
86 template<typename X_>
87 static std::shared_ptr<X_> _copy(const std::shared_ptr<X_>& x)
88 {
89 return std::dynamic_pointer_cast<X_>(x->copy());
90 }
91
92 template<typename D>
93 static void __replace_single_expr(std::shared_ptr<D>& x, const ExprID& old_expr_id, const std::shared_ptr<ExprBase>& new_expr)
94 {
95 if(x->unique_id() == old_expr_id)
96 {
97 assert(std::dynamic_pointer_cast<VarBase>(x) && "this subexpr should be some variable");
98 x = std::dynamic_pointer_cast<D>(new_expr->copy() /* todo: keep this copy? */);
99 }
100 else
101 x->replace_expr(old_expr_id, new_expr);
102 }
103
104 std::tuple<std::shared_ptr<X>...> _x;
105 };
106}