1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  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& emitterOperationFlags flags) override;
 23     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
 78     void Store(Emitter& emitterOperationFlags 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& leftconst BoundConceptKey& right);
106 inline bool operator!=(const BoundConceptKey& leftconst 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 } } // namespace cmajor::binder
126 
127 #endif // CMAJOR_BINDER_BOUND_CONSTRAINT_INCLUDED