1
2
3
4
5
6 #ifndef CMAJOR_BINDER_BOUND_CONSTRAINT_INCLUDED
7 #define CMAJOR_BINDER_BOUND_CONSTRAINT_INCLUDED
8 #include <cmajor/binder/BoundNode.hpp>
9 #include <cmajor/symbols/ConceptSymbol.hpp>
10
11 namespace cmajor { namespace binder {
12
13 using namespace cmajor::symbols;
14
15 class BoundConstraint : public BoundNode
16 {
17 public:
18 BoundConstraint(const Span& span_, const boost::uuids::uuid& moduleId_, BoundNodeType boundNodeType_);
19 virtual bool Subsume(BoundConstraint* that) const = 0;
20 virtual BoundConstraint* Clone() const = 0;
21 virtual bool IsBinaryConstraint() const { return false; }
22 void Load(Emitter& emitter, OperationFlags flags) override;
23 void Store(Emitter& emitter, OperationFlags flags) override;
24 };
25
26 class BoundAtomicConstraint : public BoundConstraint
27 {
28 public:
29 BoundAtomicConstraint(const Span& span_, const boost::uuids::uuid& moduleId_, bool satisfied_);
30 void Accept(BoundNodeVisitor& visitor) override;
31 bool Subsume(BoundConstraint* that) const override;
32 BoundConstraint* Clone() const override;
33 bool Satisfied() const { return satisfied; }
34 void SetConcept(ConceptSymbol* conceptSymbol_) { conceptSymbol = conceptSymbol_; }
35 private:
36 bool satisfied;
37 ConceptSymbol* conceptSymbol;
38 };
39
40 class BoundBinaryConstraint : public BoundConstraint
41 {
42 public:
43 BoundBinaryConstraint(const Span& span_, const boost::uuids::uuid& moduleId_, BoundNodeType boundNodeType_, BoundConstraint* left_, BoundConstraint* right_);
44 BoundBinaryConstraint(const BoundBinaryConstraint& that);
45 bool IsBinaryConstraint() const override { return true; }
46 BoundConstraint* Left() const { return left.get(); }
47 BoundConstraint* Right() const { return right.get(); }
48 private:
49 std::unique_ptr<BoundConstraint> left;
50 std::unique_ptr<BoundConstraint> right;
51 };
52
53 class BoundDisjunctiveConstraint : public BoundBinaryConstraint
54 {
55 public:
56 BoundDisjunctiveConstraint(const Span& span_, const boost::uuids::uuid& moduleId_, BoundConstraint* left_, BoundConstraint* right_);
57 BoundDisjunctiveConstraint(const BoundDisjunctiveConstraint& that);
58 bool Subsume(BoundConstraint* that) const override;
59 void Accept(BoundNodeVisitor& visitor) override;
60 BoundConstraint* Clone() const override;
61 };
62
63 class BoundConjunctiveConstraint : public BoundBinaryConstraint
64 {
65 public:
66 BoundConjunctiveConstraint(const Span& span_, const boost::uuids::uuid& moduleId_, BoundConstraint* left_, BoundConstraint* right_);
67 BoundConjunctiveConstraint(const BoundConjunctiveConstraint& that);
68 bool Subsume(BoundConstraint* that) const override;
69 void Accept(BoundNodeVisitor& visitor) override;
70 BoundConstraint* Clone() const override;
71 };
72
73 class BoundConcept : public BoundNode
74 {
75 public:
76 BoundConcept(ConceptSymbol* conceptSymbol_, const std::std::vector<TypeSymbol*>&typeArguments_, constSpan&span_, constboost::uuids::uuid&moduleId_);
77 void Load(Emitter& emitter, OperationFlags flags) override;
78 void Store(Emitter& emitter, OperationFlags flags) override;
79 void Accept(BoundNodeVisitor& visitor) override;
80 ConceptSymbol* GetConceptSymbol() const { return conceptSymbol; }
81 const std::std::vector<TypeSymbol*>&TypeArguments() const{returntypeArguments;}
82 int Arity() const { return typeArguments.size(); }
83 TypeSymbol* CommonType() const { return commonType; }
84 void SetCommonType(TypeSymbol* commonType_) { commonType = commonType_; }
85 void SetBoundConstraint(std::std::unique_ptr<BoundConstraint>&&boundConstraint_);
86 BoundConstraint* GetBoundConstraint() { return boundConstraint.get(); }
87 void AddBoundTemplateParameter(std::std::unique_ptr<BoundTemplateParameterSymbol>&&boundTemplateParameter);
88 private:
89 std::u32string name;
90 ConceptSymbol* conceptSymbol;
91 std::vector<TypeSymbol*> typeArguments;
92 TypeSymbol* commonType;
93 std::unique_ptr<BoundConstraint> boundConstraint;
94 std::vector<std::std::unique_ptr<BoundTemplateParameterSymbol>>boundTemplateParameters;
95 };
96
97 struct BoundConceptKey
98 {
99 BoundConceptKey(ConceptSymbol* conceptSymbol_, std::std::vector<TypeSymbol*>typeArguments_):conceptSymbol(conceptSymbol_), typeArguments(typeArguments_){}
100 int Arity() const { return typeArguments.size(); }
101 ConceptSymbol* conceptSymbol;
102 std::vector<TypeSymbol*> typeArguments;
103 };
104
105 bool operator==(const BoundConceptKey& left, const BoundConceptKey& right);
106 inline bool operator!=(const BoundConceptKey& left, const BoundConceptKey& right)
107 {
108 return !(left == right);
109 }
110
111 struct BoundConceptKeyHash
112 {
113 bool operator()(const BoundConceptKey& boundConceptKey) const
114 {
115 size_t hashCode = boost::hash<boost::uuids::uuid>()(boundConceptKey.conceptSymbol->TypeId());
116 int n = boundConceptKey.Arity();
117 for (int i = 0; i < n; ++i)
118 {
119 hashCode ^= boost::hash<boost::uuids::uuid>()(boundConceptKey.typeArguments[i]->TypeId());
120 }
121 return hashCode;
122 }
123 };
124
125 } }
126
127 #endif // CMAJOR_BINDER_BOUND_CONSTRAINT_INCLUDED