diff options
author | John Hodge <tpg@mutabah.net> | 2015-03-30 17:52:31 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2015-03-30 17:52:31 +0800 |
commit | ace202ef3d35cb5010e9164900c2c825dd6d3e8e (patch) | |
tree | 62fb10e28e795aef13c82d7717384b1affb3c3da | |
parent | 86e4115964dee385d167fda110ed700012168d06 (diff) | |
download | mrust-ace202ef3d35cb5010e9164900c2c825dd6d3e8e.tar.gz |
Add ordering to TypeRef and Path (to generalise operator== and operator<
-rw-r--r-- | src/ast/path.cpp | 24 | ||||
-rw-r--r-- | src/ast/path.hpp | 6 | ||||
-rw-r--r-- | src/common.hpp | 53 | ||||
-rw-r--r-- | src/types.cpp | 39 | ||||
-rw-r--r-- | src/types.hpp | 6 |
5 files changed, 105 insertions, 23 deletions
diff --git a/src/ast/path.cpp b/src/ast/path.cpp index c06a63a4..381685a9 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -25,9 +25,14 @@ const ::std::vector<TypeRef>& PathNode::args() const { return m_params; } -bool PathNode::operator==(const PathNode& x) const +Ordering PathNode::ord(const PathNode& x) const { - return m_name == x.m_name && m_params == x.m_params; + Ordering rv; + rv = ::ord(m_name, x.m_name); + if(rv != OrdEqual) return rv; + rv = ::ord(m_params, x.m_params); + if(rv != OrdEqual) return rv; + return OrdEqual; } ::std::ostream& operator<<(::std::ostream& os, const PathNode& pn) { os << pn.m_name; @@ -356,9 +361,20 @@ Path& Path::operator+=(const Path& other) return *this; } -bool Path::operator==(const Path& x) const +Ordering Path::ord(const Path& x) const { - return m_class == x.m_class && m_crate == x.m_crate && m_nodes == x.m_nodes; + Ordering rv; + + rv = ::ord( (unsigned)m_class, (unsigned)x.m_class ); + if( rv != OrdEqual ) return rv; + + rv = ::ord( m_crate, x.m_crate ); + if( rv != OrdEqual ) return rv; + + rv = ::ord( m_nodes, x.m_nodes ); + if( rv != OrdEqual ) return rv; + + return OrdEqual; } void Path::print_pretty(::std::ostream& os) const diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 1e70389d..94af94da 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -134,7 +134,8 @@ public: ::std::vector<TypeRef>& args() { return m_params; } const ::std::vector<TypeRef>& args() const; - bool operator==(const PathNode& x) const; + Ordering ord(const PathNode& x) const; + bool operator==(const PathNode& x) const { return ord(x) == OrdEqual; } void print_pretty(::std::ostream& os) const; friend ::std::ostream& operator<<(::std::ostream& os, const PathNode& pn); @@ -263,7 +264,8 @@ public: PathNode& operator[](int idx) { if(idx>=0) return m_nodes[idx]; else return m_nodes[size()+idx]; } const PathNode& operator[](int idx) const { if(idx>=0) return m_nodes[idx]; else return m_nodes[size()+idx]; } - bool operator==(const Path& x) const; + Ordering ord(const Path& x) const; + bool operator==(const Path& x) const { return ord(x) == OrdEqual; } SERIALISABLE_PROTOTYPES(); void print_pretty(::std::ostream& os) const; diff --git a/src/common.hpp b/src/common.hpp index c39f8c07..4c8d5f23 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -15,6 +15,59 @@ #include "include/rustic.hpp" // slice and option #include "include/compile_error.hpp" +enum Ordering +{ + OrdLess, + OrdEqual, + OrdGreater, +}; +template<typename T> +Ordering ord(const ::std::vector<T>& l, const ::std::vector<T>& r) +{ + unsigned int i = 0; + for(const auto& it : l) + { + if( i > r.size() ) + return OrdGreater; + + auto rv = it.ord(r[i]); + if( rv != OrdEqual ) + return rv; + + i ++; + } + + return OrdEqual; +} +static inline Ordering ord(bool l, bool r) +{ + if(l == r) + return OrdEqual; + else if( l ) + return OrdGreater; + else + return OrdLess; +} +static inline Ordering ord(unsigned l, unsigned r) +{ + if(l == r) + return OrdEqual; + else if( l > r ) + return OrdGreater; + else + return OrdLess; +} +static inline Ordering ord(const ::std::string& l, const ::std::string& r) +{ + if(l == r) + return OrdEqual; + else if( l > r ) + return OrdGreater; + else + return OrdLess; +} + + template <typename T> struct LList { diff --git a/src/types.cpp b/src/types.cpp index 0d38ae26..a5b6d6ee 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -315,42 +315,51 @@ bool TypeRef::is_concrete() const throw ::std::runtime_error( FMT("BUGCHECK - Invalid type class on " << *this) ); } -bool TypeRef::operator==(const TypeRef& x) const +Ordering TypeRef::ord(const TypeRef& x) const { - if(m_class != x.m_class) - return false; + Ordering rv; + + rv = ::ord( (unsigned)m_class, (unsigned)x.m_class ); + if(rv != OrdEqual) return rv; + switch(m_class) { case TypeRef::NONE: - return true; + return OrdEqual; case TypeRef::ANY: case TypeRef::UNIT: - return true; + return OrdEqual; case TypeRef::PRIMITIVE: - return m_core_type == x.m_core_type; + rv = ::ord( (unsigned)m_core_type, (unsigned)x.m_core_type ); + if(rv != OrdEqual) return rv; + return OrdEqual; case TypeRef::FUNCTION: - if( m_path[0].name() != x.m_path[0].name() ) - return false; + rv = ::ord(m_path[0].name(),x.m_path[0].name()); + if(rv != OrdEqual) return rv; + return OrdEqual; case TypeRef::TUPLE: - return m_inner_types == x.m_inner_types; + return ::ord(m_inner_types, x.m_inner_types); + //return m_inner_types == x.m_inner_types; case TypeRef::REFERENCE: case TypeRef::POINTER: - return m_is_inner_mutable == x.m_is_inner_mutable && m_inner_types == x.m_inner_types; + rv = ::ord(m_is_inner_mutable, x.m_is_inner_mutable); + if(rv != OrdEqual) return rv; + return ::ord(m_inner_types, x.m_inner_types); case TypeRef::ARRAY: - if(m_inner_types[0] != x.m_inner_types[0]) - return false; + rv = m_inner_types[0].ord( x.m_inner_types[0] ); + if(rv != OrdEqual) return rv; if(m_size_expr.get()) { throw ::std::runtime_error("TODO: Sized array comparisons"); } - return true; + return OrdEqual; case TypeRef::GENERIC: DEBUG(*this << " == " << x); throw ::std::runtime_error("BUGCHECK - Can't compare generic type"); case TypeRef::PATH: - return m_path == x.m_path; + return m_path.ord( x.m_path ); case TypeRef::MULTIDST: - return m_inner_types == x.m_inner_types; + return ::ord(m_inner_types, x.m_inner_types); } throw ::std::runtime_error(FMT("BUGCHECK - Unhandled TypeRef class '" << m_class << "'")); } diff --git a/src/types.hpp b/src/types.hpp index 5f7c6111..38f2b26b 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -188,8 +188,10 @@ public: void add_trait(TypeRef trait) { assert(is_wildcard()); m_inner_types.push_back( ::std::move(trait) ); }
const ::std::vector<TypeRef>& traits() const { assert(is_wildcard()); return m_inner_types; }
- bool operator==(const TypeRef& x) const;
- bool operator!=(const TypeRef& x) const { return !(*this == x); }
+ Ordering ord(const TypeRef& x) const;
+ bool operator==(const TypeRef& x) const { return ord(x) == OrdEqual; }
+ bool operator!=(const TypeRef& x) const { return ord(x) != OrdEqual; }
+ bool operator<(const TypeRef& x) const { return ord(x) == OrdLess; };
PrettyPrintType print_pretty() const { return PrettyPrintType(*this); }
|