#ifndef MT1Q5B_H #define MT1Q5B_H ///////////////////////////////////////////// // MT1Q5b.h - Scope Interface and Factory #include #include struct IScope { using Name = std::string; using Filename = std::string; using Type = std::string; using StartLine = size_t; using EndLine = size_t; using Size = size_t; using Complexity = size_t; using NumberChildren = size_t; using ChildType = std::vector; virtual ~IScope() {} template static IScope* Create(); template static IScope* Create( const Name& name, const Filename& file, const Type& type, StartLine sl, EndLine el, Complexity comp, const ChildType& childType ); virtual Name& name() = 0; virtual Filename& file() = 0; virtual Type& type() = 0; virtual StartLine& start() = 0; virtual EndLine& end() = 0; virtual Size size() const = 0; virtual Complexity& complexity() = 0; virtual NumberChildren numberChildren() const = 0; virtual ChildType& childType() = 0; virtual bool match(const IScope* pS) = 0; virtual bool operator<(const IScope* pS) = 0; }; template static IScope* IScope::Create() { return new S; } template static IScope* IScope::Create( const Name& name, const Filename& file, const Type& type, StartLine sl, EndLine el, Complexity comp, const ChildType& childType ) { return new S(name, file, type, sl, el, comp, childType); } class Scope : public IScope { public: Scope(Name n, Filename f, Type t, StartLine sl, EndLine el, Complexity c, ChildType ct) : _name(n), _file(f), _type(t), _start(sl), _end(el), _complexity(c), _childType(ct) {} Scope() {} Name& name() { return _name; } Filename& file() { return _file; } Type& type() { return _type; } StartLine& start() { return _start; } EndLine& end() { return _end; } Size size() const { return _end - _start + 1; } Complexity& complexity() { return _complexity; } NumberChildren numberChildren() const { return _childType.size(); } ChildType& childType() { return _childType; } bool match(const IScope* pS); bool operator<(const IScope* pS); private: Name _name = "unknown"; Filename _file = "unknown"; Type _type = "unknown"; StartLine _start = 0; EndLine _end = 0; Complexity _complexity = 0; ChildType _childType; }; inline bool Scope::match(const IScope* pS) { IScope* pCS = const_cast(pS); Scope::Size sizeTolerance = 2; bool sizeMatch = (this->size() < pS->size() + sizeTolerance) && (this->size() > pS->size() - sizeTolerance); Scope::Complexity complexityTolerance = 1; bool complexityMatch = (this->complexity() < pCS->complexity() + complexityTolerance) && (this->complexity() > pCS->complexity() - complexityTolerance); bool numberChildrenMatch = this->numberChildren() == pCS->numberChildren(); bool childTypeMatch = true; if (numberChildrenMatch) { for (size_t i = 0; i < this->numberChildren(); ++i) { if (this->childType()[i] != pCS->childType()[i]) { childTypeMatch = false; break; } } } else { childTypeMatch = false; } return childTypeMatch && complexityMatch /*&& sizeMatch*/; } inline bool Scope::operator<(const IScope* pS) { IScope* pCS = const_cast(pS); return this->complexity() > pCS->complexity(); } #endif